Func<;T>;在带有LinQ的Lambda表达式中

本文关键字:LinQ Lambda 表达式 lt gt Func | 更新日期: 2023-09-27 18:20:22

我对这段代码有问题。i使用LinQ实体

Dictionary<string, int> dictionary = new Dictionary<string, int>();
using (var db = new DiagEntities())
{
    PropertyInfo[] properties = typeof(DiagTab).GetProperties();
    foreach (PropertyInfo property in properties)
    {
        string name = property.Name;
        if (name == "ID_Diag") { continue; } // no column 1 and 2 
        if (name == "Reponse") { continue; } 
        Func<DiagTab, byte> accessor = (Func<DiagTab, byte>)property
                                            .GetMethod
                                            .CreateDelegate(typeof(Func<DiagTab, byte>));
        int sum = db.DiagTabs.Sum(p => accessor(p));  // invoke error
        dictionary.Add(name, sum);                      
    }
    bouba.DataSource = dictionary;
    bouba.DataBind();

一个编译我有这个错误,出现在这一行,我不明白为什么:

int sum = db.DiagTabs.Sum(p => accessor(p))

LINQ to Entities 中不支持节点类型"Invoke"LINQ表达式

你能帮我解决这个问题吗?我应该使用LINQkit还是其他?

Func<;T>;在带有LinQ的Lambda表达式中

您的代码有两个主要问题。

首先,EnumerableQueryable都没有byteSum方法,因此最接近的方法是使用int的方法。

其次,也是更重要的一点,LINQ to Entities主要与Queryable一起工作,后者反过来使用Expression<Func<...>>(与仅使用Func<...>Enumerable形成对比)。您的代码正试图通过从func创建一个表达式来组合它们,但正如错误消息所述,这是不受支持的。

解决方案是使用System.Linq.Expressions命名空间中的类/方法构建表达式-expression.Parameter用于创建参数,expression.Property用于属性访问器,expression.Convert用于更改类型,expression.Lambda用于将它们放在一起,就像这个

foreach (var property in typeof(DiagTab).GetProperties())
{    
    string name = property.Name;
    if (name == "ID_Diag") { continue; } // no column 1 and 2 
    if (name == "Reponse") { continue; } 
    // selector = (DiagTab source) => (int)source.Property
    var source = Expression.Parameter(typeof(DiagTab), "source");
    var selector = Expression.Lambda<Func<DiagTab, int>>(
        Expression.Convert(Expression.Property(source, property), typeof(int)),
        source);
   int sum = db.DiagTabs.Sum(selector);
   dictionary.Add(name, sum);                      
}