【问题标题】:Using a LINQ Where query to get only some of the ConfigurationManager.ConnectionStrings使用 LINQ Where 查询仅获取部分 ConfigurationManager.ConnectionStrings
【发布时间】:2014-12-12 17:17:28
【问题描述】:

我的目标是在控制台应用程序中对 ConfigurationManager.ConnectionStrings 集合使用 LINQ Where 查询(假设新的 .NET 4.5 控制台应用程序添加了 System.Configuration 引用和相应的 using 语句)。

我从这个开始,工作

var relevantSettings =
        ConfigurationManager.ConnectionStrings.Where(s => s.Name.StartsWith("Xyz"));

它告诉我:

方法“IEnumerable<TSource> System.Linq.Enumerable.Where<TSource(this IEnumerable<TSource>, Func<TSource,bool>)”的类型参数无法从用法中推断出来。尝试明确指定参数。

这让我措手不及,所以我尝试了这个来检查我的理智,但是这也不起作用工作

foreach (var settingsin ConfigurationManager.ConnectionStrings)
{
    if (settings.Name.StartsWith("Xyz")) Console.WriteLine("Found one!");
}

它抱怨不是关于foreach 语句,而是关于.Name 位,错误:

无法解析符号“名称”

我知道可能有什么东西阻止了编译器推断var 的类型,仔细检查我尝试了这个确实工作

foreach (ConnectionStringSettings settings in ConfigurationManager.ConnectionStrings)
{
    if (connectionString.Name.StartsWith("Xyz")) Console.WriteLine("Found one!");
}

但是,这对我没有多大帮助,除了解决我眼前的问题。我想了解这里发生了什么。

我想要做的就是使用一个简单的 LINQ Where 语句在我的 app.config 中获取连接字符串的子集。为什么编译器阻止我这样做?

【问题讨论】:

    标签: c# linq connection-string configurationmanager


    【解决方案1】:

    TL;DR 版本

    您需要发送.Cast<ConnectionStringSettings>() 来完成这项工作。

    详情

    好吧,如果你再深入一点,你可以让编译器告诉你更多:

    Func<ConnectionStringSettings, bool> StartsWithXyz = c => c.Name.StartsWith("Xyz");
    var relevantSettings = ConfigurationManager.ConnectionStrings.Where(StartsWithXyz);
    

    这是告诉你:

    无法将实例参数类型“System.Configuration.ConnectionStringSettingsCollection”转换为“System.Collections.Generic.IEnumerable&lt;System.Configuration.ConnectionStringSettings&gt;

    向上推ConnectionStringSettings 属性的继承树,您终于可以看到罪魁祸首,这很有意义:该属性属于泛型IEnumerable 类型。

    这实际上使问题成为this question 的相当复杂的副本,因为解决方案在于将非泛型属性转换为泛型列表,以便 LINQ 和编译器发挥它们的作用。对于这种特殊情况,以下可以工作

    var relevantSettings = ConfigurationManager.ConnectionStrings
                                               .Cast<ConnectionStringSettings>()
                                               .Where(c => c.Name.StartsWith("Xyz"));
    

    享受吧!

    【讨论】:

    • +1 不仅是that 的副本,还有this 我在 9 小时前回答过的副本。基本上这是因为这些类比 C# 中的泛型更老。
    • 是的,我想可能会有更多重复项,一旦您确实了解了问题,就很容易发现它们。我曾将“”功能用作橡皮鸭,帮助我找到答案。我想我的文字可能会帮助其他人搜索这个问题的这个特定实例,因为似乎没有关于 ConnectionStrings 的文字,所以我还是发布了它。
    • 这并不是批评。在这种情况下,不清楚他们为什么不让the class 实现IEnumerable&lt;ConnectionStringSettings&gt;,因为它也来自引入泛型的.NET 2.0。我猜他们在那个班级出生的时候还没有完成,
    • 啊,重点! (我从“+1”中猜到了很多,但回读我的评论,我想我暗示我感到批评)。感谢您的反馈。
    猜你喜欢
    • 2011-03-03
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多