使用Func作为LinqToEntities的参数 [英] Using Func as parameter for LinqToEntities
问题描述
.Where()
正在使用 Func< T,bool>
作为参数,我想要这样做 - 但是我没有找到一种方法来访问我的方法中的谓词。 public DenormalizedType GetData(Func< Thing,bool>谓词)
{
using(var dbContext = new MyDbContext())
{
var myData =(from some in dbContext.Thing
加入其他的dbContext.OtherThing
在some.OtherId等于other.Id
// => HowToWhere ???
选择新的DenormalizedType()
{
SomeEntry = some.Entry
SomeOtherId = some.OtherId
OtherValue = other.Value
})ToList();
}
}
我有3个有关此问题的问题。
):如何调用我的谓词来使用动态的where子句?
第二:如果我的ini tial想法不工作(因为teovankots的答案表明,我的方法对于LinqToEntities不是有效的)是否有可能,只提供一种加入方法?
第三:将结果返回到另一个软件组件是最好的方法是什么?
EF查询提供者需要将LINQ查询表达式树转换为SQL,当您传递 Func< ...>
(和更一般地,调用表达式,如委托,未知方法等)。
不久之后,您无法使用 Func< ...>
类型参数。
使用 Queryable
方法时要考虑的第一件事是使用 Expression< Func< .. 。>>
每当您在 Enumerable
中使用 Func< ..>
方法。所以改变你的方法参数:
public DenormalizedType GetData(Expression< Func< Thing,bool>> predicate)
不幸的是,使用LINQ查询语法中提供的表达式不支持开箱即用。要做到这一点,你需要一些表达式树处理库。
问题和可能的解决方案在 LINQKit 包页面。软件包提供的解决方案是通过 AsExpandable
和调用
自定义扩展方法。
安装 nuget包,添加
使用LinqKit;
到源代码文件,现在可以使用这样的东西来实现目标: p>
public DenormalizedType GetData(Expression< Func< Thing,bool>> predicate)
{
using dbContext = new MyDbContext())
{
var myData =(从dbContext.Thing.AsExpandable()中的一些)// <=
在dbContext.OtherThing
中加入其他some.OtherId等于other.Id
其中predicate.Invoke(some)//< =
select new DenormalizedType()
{
SomeEntry = some.Entry
SomeOtherId = some.OtherId
OtherValue = other.Value
})ToList();
}
}
I have a Linq-Query to get my EF-Data. My query joins 4 tables and selects the result to a denormalized type. I will need this query very often but with different predicates. The List-ExtensionMethods (e.g. .Where()
are working with a Func<T,bool>
as a parameter and I wanted to do it the same - but I don´t find a way to access my predicate in my Method.
public DenormalizedType GetData(Func<Thing, bool> predicate)
{
using (var dbContext = new MyDbContext())
{
var myData = (from some in dbContext.Thing
join other in dbContext.OtherThing
on some.OtherId equals other.Id
// => HowToWhere ???
select new DenormalizedType()
{
SomeEntry = some.Entry
SomeOtherId = some.OtherId
OtherValue = other.Value
}).ToList();
}
}
I have 3 questions regarding this issue.
First (obviously): how to invoke my predicate to use a dynamic where-clause?
Second: If my initial idea doesn´t work (because teovankots answer indicates, that my approach isn´t valid for LinqToEntities) is it somehow possible, to make a method of the join only?
Third: What is the best performing approach to return my results to another software-component?
EF query provider needs to translate the LINQ query expression tree to SQL, which is not possible when you pass a Func<...>
(and more generally, invocation expression like delegate, unknown method etc.).
Shortly, what you ask is not possible with Func<...>
type parameters.
The first thing to consider when working with Queryable
methods is to use Expression<Func<...>>
whenever you would use Func<..>
in Enumerable
methods. So change your method argument like this:
public DenormalizedType GetData(Expression<Func<Thing, bool>> predicate)
Unfortunately using the supplied expression inside LINQ query syntax is not supported out of the box. To do that, you need some expression tree processing library.
The problem and the possible solution is explained in the LINQKit package page. The solution provided by the package is through AsExpandable
and Invoke
custom extension methods.
Install the nuget package, add
using LinqKit;
to the source code file, and now you can use something like this to achieve the goal:
public DenormalizedType GetData(Expression<Func<Thing, bool>> predicate)
{
using (var dbContext = new MyDbContext())
{
var myData = (from some in dbContext.Thing.AsExpandable() // <=
join other in dbContext.OtherThing
on some.OtherId equals other.Id
where predicate.Invoke(some) // <=
select new DenormalizedType()
{
SomeEntry = some.Entry
SomeOtherId = some.OtherId
OtherValue = other.Value
}).ToList();
}
}
这篇关于使用Func作为LinqToEntities的参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!