【问题标题】:C# Linq Expression on Property of BindingListBindingList 属性上的 C# Linq 表达式
【发布时间】:2016-02-16 06:53:13
【问题描述】:

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

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

发生“System.NotSupportedException”类型的未处理异常 在 EntityFramework.SqlServer.dll 中

附加信息:指定 LINQ to Entities 不支持类型成员“计数”。仅有的 初始化器、实体成员和实体导航属性是 支持。

这是一个小例子:

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 表达式工作。

【问题讨论】:

  • 我使用的是 EF 6.1.3,但无法动态实现。如果我像这样context.Totos.Where(c =&gt; c.tatas.Count &gt; 2).ToList() 自己编写 lambda 表达式,它会起作用。 Ivan Stoev 解决方案'工作正常。

标签: c# linq lambda field bindinglist


【解决方案1】:

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

但是,如果您想要安全(而且通常更正确),您应该使用 Enumerable.Count() 方法而不是 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);
}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      查询将在ToList() 语句之后执行。将在该点和分配给 listResult 之前生成错误消息。所以问题一定是lambdaExpression的构造。错误消息说 Linq 实现不支持 BindingList。您必须将 ToList 结果转换为 BindingList。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-26
        • 1970-01-01
        • 2022-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多