gpt4 book ai didi

c# - 在 linq select 语句中使用 func 选择匿名类型的值

转载 作者:太空宇宙 更新时间:2023-11-03 16:28:36 25 4
gpt4 key购买 nike

我有一个通用类型类 Filter,它采用一些 lambda 表达式从类型中选择值,以便该类可重用。该类用于另一个通用类型类搜索,它将使用过滤器来选择最终将在下拉列表中使用的类型的不同项目。

我删除了这些不重要的代码。

public class Filter<T>
{
public string Name;
public Func<T, string> Key;
public Func<T, string> Value;
}

public class Search<T>
{
MyDBContext db = new MyDBContext();
IQueryable<T> Model = db.Stuff.OrderBy(a => a.TermID);
Filter filter = new Filter(
Name: "Term",
Value: a => a.TermID.ToString(),
Key: a => a.Term.TermType.Name
);

var filterItems = Model
.Select(a => new { Key = filter.Key(a), Value = filter.Value(a)})
.OrderBy(t => t.Key)
.Distinct()
.ToArray();
}

我收到运行时错误:The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.我尝试使用强类型而不是匿名类型,并使用 Expression<Func<T,string>>在过滤器中。

经过几个小时的搜索和尝试不同的事情后,我不确定如何让它工作。感谢您的帮助。

最佳答案

您的问题可以更简单地表达,例如重现它:

Func<SomeClass, int> x = t => t.ID;
var y = db.SomeClasses.Select(c => x(c)).ToArray();

它编译正常,但在运行时会出现相同的错误,因为您正在调用一个已编译 函数。那部分“t => t.ID”是编译代码(至少是 IL)并且 linq 无法读取它以将其转换为 SQL。它只能将表达式树转换为 SQL。上述案例的解决方案相当简单,我不确定这将如何转化为您的情况,但它应该是可能的。

Expression<Func<SomeClass, int>> x = t => t.ID;
var y = db.SomeClasses.Select(x).ToArray();

还可以选择将函数调用移动到 linq to objects,这样就不需要将其转换为 sql(在客户端处理“AsEnumerable”之后的所有内容)。这使得可以在函数中放置的内容具有更大的灵 active ,并将消除您遇到的错误类型。这也将消除调用 SqlFunctions 的需要(见下文)。缺点是从服务器返回的行数可能比需要的多。

Func<SomeClass, int> x = t => t.ID;
var y = db.SomeClasses.AsEnumerable().Select(c => x(c)).ToArray();

您的最后一个问题是 EF 不喜欢 ToString 方法,您将需要使用 SqlFunctions.StringConvert,它相当糟糕。看这里:int to string in Entity Framework

关于c# - 在 linq select 语句中使用 func 选择匿名类型的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11621062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com