使用LINQ Where查询仅获取部分ConfigurationManager.ConnectionStrings
本文关键字:ConfigurationManager ConnectionStrings 获取部 LINQ Where 查询 使用 | 更新日期: 2023-09-27 18:26:47
我的目标是在控制台应用程序中的ConfigurationManager.ConnectionStrings
集合上使用LINQ Where
查询(假设是添加了System.Configuration引用和相应的using
语句的全新.NET 4.5控制台应用程序)。
我从这个开始,它不能工作:
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
位,错误为:
无法解析符号"Name"
我知道可能有什么东西阻止编译器推断var
的类型,为了仔细检查,我尝试了是否有效的:
foreach (ConnectionStringSettings settings in ConfigurationManager.ConnectionStrings)
{
if (connectionString.Name.StartsWith("Xyz")) Console.WriteLine("Found one!");
}
然而,这对我没有多大帮助,除了解决我眼前的问题。我想了解这里发生了什么。
我只想使用一个简单的LINQ Where
语句来获取app.config中连接字符串的子集。为什么编译器阻止我这样做?
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<System.Configuration.ConnectionStringSettings>
"
向上驱动ConnectionStringSettings
属性的继承树,您终于可以看到罪魁祸首,这很有意义:该属性属于非泛型IEnumerable
类型。
这实际上使这个问题成为这个问题的一个相当复杂的重复,因为解决方案在于将非泛型属性强制转换为泛型列表,这样LINQ和编译器就可以发挥他们的魔力。对于此特定场景,以下确实有效:
var relevantSettings = ConfigurationManager.ConnectionStrings
.Cast<ConnectionStringSettings>()
.Where(c => c.Name.StartsWith("Xyz"));
享受吧!