我已经编写了一些自定义配置集合,元素等等。现在,我想做一个简单的Linq语句:
ServerDetails servers = ConfigurationManager.GetSection("serverDetails") as ServerDetails;
var server = from s in servers
where s.Name == serverName
select s;
我收到错误:
无法找到源类型的查询模式的实现 'MyNamespace.ServerDetails'。 '哪里'找不到。
ServerElement
有两个属性:
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;
,因为我在同一个班级中使用它。
答案 0 :(得分:38)
好的,鉴于它全部是弱类型的,你需要明确地调用Cast<>
或OfType<>
,或者给range变量赋一个显式类型。您还需要在ServerCollection
上指定ServerDetails
属性。例如:
ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
where s.Name == serverName
select s;
答案 1 :(得分:17)
在他的IEnumerable&lt; T&gt;中使用 yield return 的Brian Gideon's simple example实现,我能够枚举我的ConfigurationElementCollection。
它看起来像这样(使用原始问题):
public sealed class ServerCollection : ConfigurationElementCollection,
IEnumerable<ServerElement>
{
...
public new IEnumerator<ServerElement> GetEnumerator()
{
foreach (var key in this.BaseGetAllKeys())
{
yield return (ServerElement)BaseGet(key);
}
}
}
虽然我没有收到错误:
无法找到源类型&#39; MyNamespace.ServerDetails&#39;的查询模式的实现。 &#39;凡&#39;找不到
...我无法使用LINQ迭代我的ConfigurationElementCollection。这个解决方案解决了我的问题,因此我可以使用LINQ迭代我的集合。
答案 2 :(得分:0)
var server = ((ServerDetails) ConfigurationManager.GetSection("serverDetails")).
ServerCollection.Cast<ServerElement>().FirstOrDefault(x => x.Name == serverName);
答案 3 :(得分:0)
一个很晚的答案,我将使用此扩展类将任何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);