问题
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"));
It tells me that:
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!");
}
It complains not about the foreach
statement, but about the .Name
bit, with the error:
Could not resolve symbol 'Name'
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.
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?
回答1:
TL;DR Version
You need to do a .Cast<ConnectionStringSettings>()
to make this work.
Details
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);
This is tells you:
Cannot convert instance argument type '
System.Configuration.ConnectionStringSettingsCollection
' to 'System.Collections.Generic.IEnumerable<System.Configuration.ConnectionStringSettings>
'
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.
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"));
Enjoy!
来源:https://stackoverflow.com/questions/26419655/using-a-linq-where-query-to-get-only-some-of-the-configurationmanager-connection