使用表达式<func <>&gt;在LINQ查询</func <>中

时间:2014-10-28 20:58:52

标签: c# linq entity-framework

我想定义一个名为Func<ProductItemVendor, bool>的{​​{1}}过滤器表达式,它可以在我的整个应用程序中使用,主要是在Entity Framework / LINQ查询中。

我已经了解到,为了能够在LINQ查询中使用此过滤器,我必须将其声明为CompareProductItemVendorIds,而不仅仅是Expression<Func<>>。我理解这个的原因,这对我来说很容易。

但是我在查询中使用该表达式会遇到以下问题。

首先,代码如:

Func<>

注意:ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds) 是一个数据库实体,其ProductItem属性是导航集合。

产生错误:

  

`Instance参数:无法从'System.Collections.Generic.ICollection'转换为'System.Linq.IQueryable'

其次,代码如:

ProductItemVendors

产生错误:

  

'CompareProductItemVendorIds'是'变量',但用作'方法'

所以我有一个漂亮的新亮var results = from v in Repository.Query<ProductItemVendor>() where CompareProductItemVendorIds(v) select v; 。如何在LINQ查询中使用它?

3 个答案:

答案 0 :(得分:2)

ProductItem已经是Entity,因此您无法使用您的表达式,您需要使用Compile()从您的{Func<>获取Expression<Func<>> {1}}因为ProductItemVendors不再是IQueryable

ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds.Compile())

您必须在ProductItemVendorsContext上使用Expression,如下所示:

var item = Context.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds);

您无法在查询语法中使用Expression,您需要使用方法sytanx

var results = from v in Repository.Query<ProductItemVendor>()
                                  .Where(CompareProductItemVendorIds)
              select v;

答案 1 :(得分:0)

第一种情况;

ProductItemVendor productItemVendor = ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds);

产生错误:

`Instance argument: cannot convert from 'System.Collections.Generic.ICollection' to 'System.Linq.IQueryable'

发生,因为它是ICollection,实体已经加载。鉴于dbContextobjectContext延迟加载与显式加载的实现略有不同,我假设您正在使用显式加载。如果您将加载更改为延迟,则ProductItemVendors的类型将为IQueryable,您尝试的内容将成功。

鉴于第二种情况,表达式必须可编译为SQL,否则会出现许多奇怪的错误,可能在这种情况下可能就是这种情况。

鉴于问题中的信息,我很难给你更明确的帮助,我无法轻易地重新创建它。如果你可以创建一个MWE解决方案并将其上传到某个地方我可以看看,但我担心我在这里可以提供更多帮助。

答案 2 :(得分:0)

我认为默认情况下不支持编写这样的表达式。
您可以尝试LINQKit

这是LINQKit页面上的示例;一个class ForgotPasswordController extends Controller { use SendsPasswordResetEmails { sendResetLinkEmail as unused; } ... public function sendResetLinkEmail(Request $request) { $this->validateEmail($request); $response = $this->broker()->sendResetLink( $request->only('email') ); //Return the response if ($response == Password::RESET_LINK_SENT) { return response()->json(array( 'result' => 'ok', ), 200); } else { return response()->json(array( 'result' => 'fail', ), 500); } } } 位于另一个内部:

  

调用Invoke调用内部表达式调用Final扩展   结果。例如:

Expression<Func<>>
     

(Invoke和Expand是LINQKit中的扩展方法。)这是输出:

Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000;
Expression<Func<Purchase,bool>> criteria2 = p => criteria1.Invoke (p)
                                                 || p.Description.Contains ("a");

Console.WriteLine (criteria2.Expand().ToString()); 
     

请注意,我们有一个清晰的表达:对Invoke的调用已   被剥夺了。