考虑以下linq查询:
from r in result
join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into jOnOrderUS
from oUS in jOnOrderUS.DefaultIfEmpty()
let OnOrderUS = oUS != null ? oUS.UnitQty : 0
select (new Func<ItemMinMaxView>(() =>
{
r.OnOrderUS = OnOrderUS;
return r;
})).Invoke()
我想从结果中选择r,但是用oUS中的数据填充一个字段。有更好的方法吗?
答案 0 :(得分:2)
我宁愿把你的功能分成它的组成部分。初始查询(连接,投影等),变异,然后返回您需要的特定结果。如
var query = from r in result
join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into jOnOrderUS
from oUS in jOnOrderUS.DefaultIfEmpty()
let OnOrderUS = oUS != null ? oUS.UnitQty : 0
select new { r, OnOrderUS };
foreach (var item in query)
{
item.r.OnOrderUS = item.OnOrderUS;
}
return query.Select(item => item.r);
// assumes this is in a method returning IEnumerable<R>
如果您不想编写foreach代码,可以像这样编写代码。我不喜欢查询中的突变,但这会做你想要的
Func<R, int, R> mutateR = (r, onOrderUS) => { r.OnOrderUS = onOrderUS; return r; };
var query = from r in result
join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into jOnOrderUS
from oUS in jOnOrderUS.DefaultIfEmpty()
let OnOrderUS = oUS != null ? oUS.UnitQty : 0
select mutateR(r, OnOrderUS);
答案 1 :(得分:1)
我也希望将查询分成更多逻辑部分以帮助提高可读性。但是我会利用Reactive Extensions (Rx)来产生你想要的副作用(即值赋值)。
首先我会像Anthony建议的那样创建查询,但我想检查一下你的查询是否正确。
如果返回了多个onOrderUS
条记录,那么您只会将找到的最后一条记录分配给ItemMinMaxView
记录。
如果只有零个或一个记录,那么你的查询就可以了,但它可能更简单。
无论哪种方式,请尝试此查询:
var query =
from r in result
join oUS in onOrderUS on r.ItemGUID equals oUS.ItemGUID into goUSs
let OnOrderUS = goUSs.Sum(x => x.UnitQty)
select new
{
Result = r,
OnOrderUS
};
然后我会得到最终结果(具有分配副作用),如下所示:
var output = query
.Do(x => x.Result.OnOrderUS = x.OnOrderUS)
.Select(x => x.Result)
.ToArray();
.Do(...)
方法是Rx的一部分,并明确指出这些副作用。
你在Rx中为IEnumerable<T>
获得了很多好的扩展方法,所以如果你没有检查过它,你应该这样做。它甚至最近被提升为supported Microsoft developer tool。