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

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

问题描述

我有了一个泛型类过滤器需要一些lambda表达式以便类是可重复使用从类型选择值。这个类是将使用过滤器来选择最终将在下拉列表中使用的类型的不同项目的另一个泛型类的搜索使用。

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支持实体
我已经使用强类型而不是匿名类型,并使用表达式来审判; Func键< T,串> ;> 在过滤器

在搜索和尝试不同的东西的时间,我不知道如何使这项工作。
谢谢你的帮助。

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

推荐答案

您的问题可以更简单地表示,比如,这也再现:

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



它编译罚款,但给人在运行时同样的错误,因为你调用的编译功能。这部分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();



还有移动所述函数调用入LINQ到对象,以便它不需要的选项翻译(AsEnumerable在客户端上处理后的所有内容)到SQL。这使得在有什么可以被放置在函数更大的灵活性,并消除您得到错误的类型。这也将消除对呼叫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在实体框架串

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天全站免登陆