使用LINQ Where查询仅获取一些ConfigurationManager.ConnectionStrings [英] Using a LINQ Where query to get only some of the ConfigurationManager.ConnectionStrings
问题描述
我的目标是在控制台应用程序中的ConfigurationManager.ConnectionStrings
集合上使用LINQ Where
查询(假设添加了System.Configuration引用的新.NET 4.5控制台应用程序和相应的using
语句).
My goal is to use a LINQ Where
query on the ConfigurationManager.ConnectionStrings
collection in a console application (assume a fresh .NET 4.5 console application with a System.Configuration reference added, and a correspodning using
statement).
我从这里开始,它无效有效:
I started with this, which does not work:
var relevantSettings =
ConfigurationManager.ConnectionStrings.Where(s => s.Name.StartsWith("Xyz"));
它告诉我:
无法从用法中推断出方法'
IEnumerable<TSource> System.Linq.Enumerable.Where<TSource(this IEnumerable<TSource>, Func<TSource,bool>)
'的类型参数.尝试显式指定参数.
The type arguments for method '
IEnumerable<TSource> System.Linq.Enumerable.Where<TSource(this IEnumerable<TSource>, Func<TSource,bool>)
' cannot be inferred from the usage. Try specifying the arguments explicitly.
这使我措手不及,所以我尝试这样做来检查自己的理智,但是这不有效:
This caught me off guard, so I tried this to check my sanity, but this does not work either:
foreach (var settingsin ConfigurationManager.ConnectionStrings)
{
if (settings.Name.StartsWith("Xyz")) Console.WriteLine("Found one!");
}
它抱怨foreach
语句,而是关于.Name
位,并且报错:
It complains not about the foreach
statement, but about the .Name
bit, with the error:
无法解析符号名称"
Could not resolve symbol 'Name'
我了解到,可能有某种阻止编译器推断var
类型的方法,请仔细检查我是否尝试了可行的这种方法:
I understand that there's probably something preventing the compiler from inferring the var
's type, to double check I tried this which does work:
foreach (ConnectionStringSettings settings in ConfigurationManager.ConnectionStrings)
{
if (connectionString.Name.StartsWith("Xyz")) Console.WriteLine("Found one!");
}
但是,除了解决我眼前的问题之外,这对我没有太大帮助.我想了解这是怎么回事.
However, that doesn't help me very much, except for solving my immediate problem. I want to understand what is going on here.
我要做的就是使用简单的LINQ Where
语句在我的app.config中获取连接字符串的子集.为什么编译器阻止我这样做?
All I wanted to do is use a simple LINQ Where
statement to get a subset of the connection strings in my app.config. Why is the compiler preventing me from doing this?
推荐答案
TL; DR版本
您需要执行.Cast<ConnectionStringSettings>()
才能完成此工作.
TL;DR Version
You need to do a .Cast<ConnectionStringSettings>()
to make this work.
好吧,如果您进行更深入的研究,您可以让编译器告诉您更多信息:
Well, if you dig even a little deeper, you can get the compiler to tell you even more:
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
属性的继承树开始,您最终可以看到罪魁祸首,这很有道理:该属性属于 non 通用IEnumerable
类型.
Driving up the inheritance tree of the ConnectionStringSettings
property you can finally see the culprit, which makes a lot of sense: that property is of the non generic IEnumerable
type.
实际上,这使该问题与此问题相当复杂,因为解决方案在于投射非将通用属性更改为通用列表,以便LINQ和编译器可以发挥作用.对于这种特定情况,可以执行以下 :
This in fact makes the question a rather elaborate duplicate of this question, as the solution lies in casting the non-generic property to a generic list, so that LINQ and the compiler may do their magic. For this particular scenario, the following does work:
var relevantSettings = ConfigurationManager.ConnectionStrings
.Cast<ConnectionStringSettings>()
.Where(c => c.Name.StartsWith("Xyz"));
享受!
这篇关于使用LINQ Where查询仅获取一些ConfigurationManager.ConnectionStrings的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!