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?
LINQ Where is a LINQ extension method which is used to filter the collection of elements based on the given condition? The condition can be precise as Func delegate type or in the lambda expression. This will be applicable in method syntax as well as in query syntax. In a single query, we can do multiple where extension methods.
It applies in both method and query syntax whereas method syntax requires the lambda expression and query syntax requires only the expression. The LINQ Where is used to limit the number of records from select, update, delete statements. Given below are few examples of LINQ where code the list of elements in the collection.
How Where Works in LINQ? The main purpose of LINQ where is used to filter elements based on the conditions. It comes under the filtering operator category. It applies in both method and query syntax whereas method syntax requires the lambda expression and query syntax requires only the expression.
The where clause is only used to extract records from select, delete, update and so on. Following is the syntax of using LINQ where clause filtering operator in method syntax to get data from collection list based on conditions. IEnumerable<string> result = countries.Where (x => x.StartsWith ("A"));
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);
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With