如何选择一个变量加上Linq中的其他一些字段来对象?

时间:2011-01-26 18:44:34

标签: c# linq

考虑以下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中的数据填充一个字段。有更好的方法吗?

2 个答案:

答案 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