在linq select语句中使用func选择匿名类型的值 [英] Select values in anonymous type with func in linq select statement

查看:182
本文介绍了在linq select语句中使用func选择匿名类型的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a generic type class Filter that has takes some lambda expressions to select values from the type so that the class is reusable. That class is used in another generic type class Search which will use Filter to select distinct items of the type which will eventually be used in a drop down list.

我删除了不重要的代码。

I removed the unimportant code for these.

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

我得到运行时错误: LINQ表达式LINQ to Entities不支持节点类型Invoke。
我尝试使用强类型而不是匿名类型,并使用表达式< Func< T,string> ;< / code>在过滤器。

I get the run time error: The LINQ expression node type 'Invoke' is not supported in LINQ to Entities. I have tried using strong types instead of anonymous types, and using Expression<Func<T,string>> in Filter.

经过几个小时的搜索和尝试不同的事情,我不知道如何使这项工作。
感谢您的帮助。

After hours of searching and trying different things, I'm not sure how to make this work. Thank you for your help.

推荐答案

您的问题可以更简单地表达,例如: / p>

Your problem can be expressed much more simply, eg this reproduces it:

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

它编译正常,但在运行时提供相同的错误,因为您正在调用 em>函数。那个部分t => t.ID是符合代码(至少是IL),linq不能读取它将其转换为SQL。它只能将表达式树转换为SQL。上述情况的解决方案相当简单,我不知道这将如何转化为您的情况,但应该是可能的。

It compiles fine but gives the same error at runtime because you are invoking a compiled function. That part "t => t.ID" is complied code (at least to IL) and linq cannot read this to convert it to SQL. It can only convert an expression tree to SQL. The solution to the above case is fairly simple, I'm not sure how this will translate to your situation but it should be possible.

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

还可以将函数调用移动到对象中,使其不需要要翻译成sql(在AsEnumerable之后的所有内容都在客户端处理)。这允许在功能中放置的更大的灵活性,并且将消除您所获得的错误类型。这也将消除调用SqlFunctions的需要(见下文)。缺点是从服务器可能会返回更多的行。

There is also the option of moving the function call into linq to objects so that it doesn't need to be translated to sql (everything after "AsEnumerable" is processed on the client). This allows much greater flexibility in what can be placed in the function and will eliminate the type of errors you are getting. This will also eliminate the need for call to SqlFunctions (see below). The downside is that more rows might be returned than needed from the server.

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

您最后一个问题是EF不喜欢ToString方法,您将需要使用SqlFunctions。 StringConvert是相当肮脏的。请参阅: int to Entity Framework

Your last problem is that EF doesn't like the ToString method and you will need to use SqlFunctions.StringConvert which is fairly crappy. See here: int to string in Entity Framework

这篇关于在linq select语句中使用func选择匿名类型的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆