Note that the _src inherit IQueryable<U>
and V inherit new()
;
I wrote the following statement, there is no syntax error.
IQueryable<V> a = from s in _src where (s.Right - 1 == s.Left) select new V();
But if i RE-wrote it as follows, the Visual Studio editor complains an error in the "Select"
IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(s=> new V());
The Error is:
The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
Candidates are:
System.Collections.Generic.IEnumerable<V> Select<U,V>(this System.Collections.Generic.IEnumerable<U>, System.Func<U,V>) (in class Enumerable)
System.Linq.IQueryable<V> Select<U,V>(this System.Linq.IQueryable<U>, System.Linq.Expressions.Expression<System.Func<U,V>>) (in class Queryable)
Could anyone explain this phenomenon, and what the solution is to fix the error?
=== Edit (2010-03-16 5:35pm) ===
Thanks Mike Two. I also tried a simple example like you. It works but this does not do in mine. I posted the code as follows:
public class NSM<U, V> where U : IQueryable<U> where V : new()
{
private U _src;
public NSM(U source) { _src = source; }
public IQueryable<V> LeafNodes
{
get
{
return from s in _src where (s.Right - 1 == s.Left) select new V();
}
}
}
I want the LeafNodes function to be rewritten into linq method chain method. Any Idea?
What is the type of _src? Does it directly implement IQueryable? I ask because I can get a simplified example of what you are showing to work.
IQueryable< int > ints = Enumerable.Range( 4, 12 ).AsQueryable();
IQueryable< decimal > foo = from s in ints where s > 7 select s * 4.2m;
IQueryable< decimal > bar = ints.Where( s => s > 7 ).Select( s => s * 4.2m );
Both of those selects work for me. I think if the compiler knows that ints (or in your case _src) is an IQueryable then it will call the right overload. Or am I completely missing something? Perhaps I oversimplified it and lost a bit of detail.
EDIT: Extending this to use the new sample code with some changes.
The trick is that Queryable.Select
takes an Expression<Func<X, V>>
and Enumerable.Select
takes a Func<X,V>
So you just need to provide an Expression
version to Select
public interface ILeftRight
{
int Right { get;}
int Left { get; }
}
public class NSM<X, U, V> where U : IQueryable<X> where X : ILeftRight where V : new()
{
private readonly U _src;
public NSM(U source) { _src = source; }
public IQueryable<V> LeafNodes
{
get
{
//return from s in _src where (s.Right - 1 == s.Left) select new V();
Expression< Func< X, V > > expression = s => new V();
return _src.Where( s => s.Right - 1 == s.Left ).Select( expression );
}
}
}
Or from the original code
Expression<Func<X,V>> expression = s => new V();
IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(expression);
The error occurres because compiler cannot choose what methods you want to be executed: Select
extension method for IEnumerable<T>
or Select
extension method for IQueryable<T>
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