Nei*_*ski 4 c# linq lambda entity-framework-core
我希望能够在我的 Entity Framework Core 2.0 查询中重用我选择的 lambda 表达式的片段。
例如:
var result = await ctx.Customers
.Select(cust => new CustomerDto {
CustomerId = cust.Id,
CustomerName = cust.Name,
CurrentValue = cust.Orders
.Where(order => order.OrderDate >= DateTime.Now.AddDays(-30)
.Sum(order => order.TotalValue)
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
由于我可能想计算CurrentValue
其他查询中的属性(实际上子查询比这更复杂),我理想情况下希望将上述代码重构为:
var result = await ctx.Customers
.Select(cust => new CustomerDto {
CustomerId = cust.Id,
CustomerName = cust.Name,
CurrentValue = CalculateCustomerCurrentValueExpr(cust)
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
我已经使用 a创建了 Linq谓词Linq.Expression
,但是我一直无法找到将 anExpression
作为 select 语句元素的方法。
任何帮助将非常感激。
对于任何感兴趣的人,我运行了十次测试代码,结果如下:
Standard Inline Code: 17ms (58,609 ticks)
With .AsExpandable() and inline code 16ms (58,029 ticks)
With .AsExpandable() and .Invoke() 16ms (58,224 ticks)
我怀疑如果运行了更多的测试周期,所有三个场景的平均处理时间将是相同的——至少在我可以测量的准确度水平上(simple StopWatch()
)。
感谢所有贡献者,特别是 SergeyA 的解决方案和 Ivan Stoev 的简单解释 .AsExpandable()
您可以使用来自 LinqKit 库 ( http://www.albahari.com/nutshell/linqkit.aspx ) 的AsExpandable 扩展重用表达式。
例子:
Expression<Func<Customer,long>> func = c => c.Orders
.Where(order => order.OrderDate >= DateTime.Now.AddDays(-30)
.Sum(order => order.TotalValue);
var result = await ctx.Customers
.AsExpandable() // this allow to unwrap injected expression
.Select(cust => new CustomerDto {
CustomerId = cust.Id,
CustomerName = cust.Name,
CurrentValue = func.Invoke(cust) // this inject predefined expression
})
.ToListAsync();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1363 次 |
最近记录: |