33

我已经编写了一些自定义配置集合、元素等。现在,我想做一个简单的 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;定义为我在同一个班级的其他地方使用它。

4

4 回答 4

41

好的,鉴于它都是弱类型的,您需要调用Cast<>OfType<>显式,或者为范围变量提供显式类型。您还需要ServerCollectionServerDetails. 例如:

ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
             where s.Name == serverName
             select s;
于 2011-12-07T10:33:37.767 回答
22

使用Brian Gideon在他的 IEnumerable<T> 实现中的yield 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 对我的集合进行迭代。

于 2015-04-08T20:10:26.447 回答
3
 var server = ((ServerDetails) ConfigurationManager.GetSection("serverDetails")).
      ServerCollection.Cast<ServerElement>().FirstOrDefault(x => x.Name == serverName);
于 2018-09-09T01:33:33.120 回答
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);
于 2020-03-30T05:39:54.040 回答