カスタム構成コレクション、要素などをいくつか作成しました。ここで、簡単なLinqステートメントを実行します。
ServerDetails servers = ConfigurationManager.GetSection("serverDetails") as ServerDetails;
var server = from s in servers
where s.Name == serverName
select s;
エラーが発生します:
ソースタイプ 'MyNamespace.ServerDetails'のクエリパターンの実装が見つかりませんでした。 「どこ」が見つかりません。
ServerElement
には2つのプロパティがあります。
public class ServerElement : ConfigurationElement
{
[ConfigurationProperty("ip")]
public string IP
{
get { return (string)base["ip"]; }
set { base["ip"] = value; }
}
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
get { return (string)base["name"]; }
set { base["name"] = value; }
}
}
ServerDetails
public sealed class ServerDetails : ConfigurationSection
{
[ConfigurationProperty("ServerCollection")]
[ConfigurationCollection(typeof(ServerCollection), AddItemName = "add")]
public ServerCollection ServerCollection
{
get { return this["ServerCollection"] as ServerCollection; }
}
}
ServerCollection
public sealed class ServerCollection : ConfigurationElementCollection
{
public void Add(ServerElement ServerElement)
{
this.BaseAdd(ServerElement);
}
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
}
protected override ConfigurationElement CreateNewElement()
{
return new ServerElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServerElement)element).Name;
}
}
何か不足していますか? Linqをカスタム構成要素で使用できるように何かを追加する必要がありますか?
ちなみに、私はusing System.Linq;
同じクラス内の他の場所で使用しているため、定義されています。
わかりました。すべて型が弱いため、Cast<>
またはOfType<>
を明示的に呼び出すか、範囲変数に明示的な型を指定する必要があります。また、ServerCollection
でServerDetails
プロパティを指定する必要があります。例えば:
ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
where s.Name == serverName
select s;
IEnumerable <T>実装で Brian Gideonの簡単な例 ofyield returnを使用して、ConfigurationElementCollectionを列挙できました。
次のようになります(元の質問を使用)。
public sealed class ServerCollection : ConfigurationElementCollection,
IEnumerable<ServerElement>
{
...
public new IEnumerator<ServerElement> GetEnumerator()
{
foreach (var key in this.BaseGetAllKeys())
{
yield return (ServerElement)BaseGet(key);
}
}
}
エラーが発生していない間:
ソースタイプ 'MyNamespace.ServerDetails'のクエリパターンの実装が見つかりませんでした。 「どこ」が見つからない
... LINQを使用してConfigurationElementCollectionを反復処理することもできませんでした。このソリューションで問題が解決され、LINQを使用してコレクションを反復処理できるようになりました。
var server = ((ServerDetails) ConfigurationManager.GetSection("serverDetails")).
ServerCollection.Cast<ServerElement>().FirstOrDefault(x => x.Name == serverName);
非常に遅い答えですが、この拡張クラスを使用して、ConfigurationElementCollectionをIEnumerableに安全に変換します。
public static class ConfigurationElementCollectionExtension
{
public static IEnumerable<T> ToEnumerable<T>(this ConfigurationElementCollection collection)
{
foreach (var element in collection)
{
if (element is T)
yield return (T)element;
yield return default;
}
}
}
以下の使用例
ConfigurationManager
.GetSection("serverDetails"))
.ServerCollection
.ToEnumerable<ServerElement>()
.FirstOrDefault(x => x.Name == serverName);