C# Linq 表达式在 BindingList 的属性上

本文关键字:属性 BindingList Linq 表达式 | 更新日期: 2023-09-27 18:34:53

我构造了一个动态搜索linq表达式。

我可以计算列表中的记录数,但如果将列表更改为绑定列表,则无法在 Lambda 表达式中使用属性 Count。我收到以下错误:

发生类型为"系统.不支持的异常"的未处理异常 in EntityFramework.SqlServer.dll

附加信息:指定的 类型成员"计数"在 LINQ to 实体中不受支持。只 初始值设定项、实体成员和实体导航属性为 支持。

下面是一个小示例:

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

我按如下方式进行查询:

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);
}

如果 tatas 的类型为 List,则此代码效果很好,但我无法弄清楚如何使用 BindingList 上的 Count 属性来使我的 lambda 表达式正常工作。

C# Linq 表达式在 BindingList 的属性上

它在最新的 EF (v6.1.3( 中工作(支持(。

但是,如果您想安全(并且通常更正确(,而不是Count属性,您应该使用Enumerable.Count()肯定支持

的方法,例如
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);
}
这个问题

的可能副本?如果 Count 属性未映射到数据库列,则不能在Where()逗号中使用它。

查询

将在 ToList() 语句之后执行。错误消息将在该点上生成,并在 listResult 之前生成。所以问题一定出在lambdaExpression的构造上。错误消息指出 Linq 实现不支持 BindingList。您必须将 ToList 结果转换为绑定列表。