我想定义一个名为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查询中使用它?
答案 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
,实体已经加载。鉴于dbContext
或objectContext
延迟加载与显式加载的实现略有不同,我假设您正在使用显式加载。如果您将加载更改为延迟,则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的调用已 被剥夺了。