0

I construct a dynamic search linq expression.

I'm able to count the number of records in a List but if I change the List to a BindingList I can't use the property Count in my Lambda expression. I get the following error:

An unhandled exception of type 'System.NotSupportedException' occurred in EntityFramework.SqlServer.dll

Additional information: The specified type member 'Count' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

Here is a little sample:

public class Toto 
{
BindingList<Tata> tatas; // or List<Tata> tatas;
}

I make the query as following:

var c = System.Linq.Expressions.Expression.Parameter(typeof(Toto), c);
var member = System.Linq.Expressions.Expression.PropertyOrField(c, "tatas");
var memberCount = System.Linq.Expressions.Expression.PropertyOrField(member, "Count");
var constantValue = System.Linq.Expressions.Expression.Constant(2);
var countExpression = System.Linq.Expressions.Expression.Equal(memberCount, constantValue);
var lambdaExpression = System.Linq.Expressions.Expression.Lambda<Func<Bike, bool>>(countExpression, c);
using (var context = new Context())
{
    var listResult = context.Totos.Where(lambdaExpression).ToList();
    Console.WriteLine(listResult.Count);
}

If tatas is of type List this code works great but I can't figure out how I can use the Count property on BindingList to make my lambda expression work.

Seth
  • 8,213
  • 14
  • 71
  • 103
  • I use EF 6.1.3 but I can't make it dynamically. It works if I write the lambda expression myselft like this `context.Totos.Where(c => c.tatas.Count > 2).ToList()`. The Ivan Stoev solution' works fine. – Zephyrin Feb 16 '16 at 09:02

3 Answers3

1

It is working (supported) in the latest EF (v6.1.3).

However, if you want to be safe (and in general is more correct), instead of Count property you should use Enumerable.Count() method which for sure is supported like this

var c = Expression.Parameter(typeof(Toto), c);
var member = Expression.PropertyOrField(c, "tatas");
var elementType = member.Type.GetInterfaces()
    .Single(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
    .GetGenericArguments()[0];
var memberCount = Expression.Call(typeof(Enumerable), "Count", 
    new [] { elementType }, member);
var constantValue = Expression.Constant(2);
var countExpression = Expression.Equal(memberCount, constantValue);
var lambdaExpression = Expression.Lambda<Func<Toto, bool>>(countExpression, c);
using (var context = new Context())
{
    var listResult = context.Totos.Where(lambdaExpression).ToList();
    Console.WriteLine(listResult.Count);
}
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
0

Possible copy of this question? If your Count property is not mapped to a database column, you cannot use it in the Where() commmand.

Community
  • 1
  • 1
Mauro
  • 2,032
  • 3
  • 25
  • 47
0

The query will be executed after the ToList() statement. The error message will be generated on that point and before the assigment to listResult. So the problem must be the construction of lambdaExpression. The error message says that the Linq implementation does not support BindingList. You have to convert the ToList result to a BindingList.

Jeroen Heier
  • 3,520
  • 15
  • 31
  • 32