ConfigurationElementCollection 和 Linq

发布于 2024-12-20 02:52:02 字数 1956 浏览 3 评论 0原文

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

I've written some custom configuration collections, elements etc. Now, I'd like to do a simple Linq statement:

ServerDetails servers = ConfigurationManager.GetSection("serverDetails") as ServerDetails;
var server = from s in servers
             where s.Name == serverName
             select s;

I get the error:

Could not find an implementation of the query pattern for source type
'MyNamespace.ServerDetails'. 'Where' not found.

The ServerElement has two properties:

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;
    }
}

Am I missing something? Do I need to add something in so that I can use Linq with a custom configuration element?

By the way, I have using System.Linq; defined as I'm using it else where within the same class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

多像笑话 2024-12-27 02:52:02

好的,考虑到它都是弱类型的,您需要显式调用 Cast<>OfType<>,或者为范围变量提供显式类型。您还需要在 ServerDetails 上指定 ServerCollection 属性。例如:

ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
             where s.Name == serverName
             select s;

Okay, given that it's all weakly typed, you'll need to either call Cast<> or OfType<> explicitly, or give an explicit type to the range variable. You'll also need to specify the ServerCollection property on your ServerDetails. For example:

ServerDetails servers = (ServerDetails) ConfigurationManager.GetSection("serverDetails");
var server = from ServerElement s in servers.ServerCollection
             where s.Name == serverName
             select s;
不知所踪 2024-12-27 02:52:02

在他的 IEnumerable中使用 Brian Gideon 的简单示例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 来迭代我的集合。

Using Brian Gideon's simple example of yield return in his IEnumerable<T> implementation, I was able to enumerate over my ConfigurationElementCollection.

It would look something like this (using the original question):

public sealed class ServerCollection : ConfigurationElementCollection,
    IEnumerable<ServerElement>
{
    ...

    public new IEnumerator<ServerElement> GetEnumerator()
    {
        foreach (var key in this.BaseGetAllKeys())
        {
            yield return (ServerElement)BaseGet(key);
        }
    }
}

While I was NOT getting the error:

Could not find an implementation of the query pattern for source type 'MyNamespace.ServerDetails'. 'Where' not found

...I was not able to iterate over my ConfigurationElementCollection using LINQ, either. This solution fixed my problem so that I could use LINQ to iteration over my collection.

深陷 2024-12-27 02:52:02
 var server = ((ServerDetails) ConfigurationManager.GetSection("serverDetails")).
      ServerCollection.Cast<ServerElement>().FirstOrDefault(x => x.Name == serverName);
 var server = ((ServerDetails) ConfigurationManager.GetSection("serverDetails")).
      ServerCollection.Cast<ServerElement>().FirstOrDefault(x => x.Name == serverName);
不离久伴 2024-12-27 02:52:02

一个很晚的答案,我将使用这个扩展类将任何 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);

A very late answer, I would use this extension class to turn any ConfigurationElementCollection into an IEnumerable safely.

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;
        }
    }
}

Example usage below

ConfigurationManager
   .GetSection("serverDetails"))
   .ServerCollection
   .ToEnumerable<ServerElement>()
   .FirstOrDefault(x => x.Name == serverName);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文