我将使用一些基本的精简示例来说明我的问题。
我有一个班级:
class Item
{
int ID;
bool Selected;
}
现在假设我有两个Item
类列表:
List<Item> ListA = GetListA();
List<Item> ListB = GetListB();
现在我想创建一个包含ListB
所有项目的第三个列表。重要的是,如果在ID
中找到匹配项(相同ListA
),那么我想使用该Selected
值,否则我希望保留Selected
值{ ListB
中的项目。
我正在创建第三个列表,如下所示:
List<Item> ListC = from item in ListB
select new Item
{
ID = item.ID,
Selected = item.Selected// <-- should use value form ListA if available
};
重要:我不想显得无知,但我不想要改变创建ListC
的方式。我的意思是我想使用“linq选择”方法,我想使用一个“一个班轮”来分配Selected
值...我知道还有其他方法来创建列表,它将工作很好,但后来我不会学到任何新东西。
到目前为止,我尝试过几件事......
我知道这会有效,但我不想两次查询ListA
:
Selected = ListA.Any(x => x.ID == item.ID) ? ListA.First(x => x.ID == item.ID).Selected : item.Selected
并且我也尝试使用DeafultIfEmpty
,但我认为这种情况并不合适......因为它不起作用,如果ListA
它似乎更有用是空的(我不在乎)
答案 0 :(得分:7)
您可以按如下方式修改最后一行代码:
Selected = (ListA.FirstOrDefault(x => x.ID == item.ID) ?? item).Selected;
对于DefaultIfEmpty
,您必须执行
Selected = ListA.Where(x => x.ID == item.ID).DefaultIfEmpty(item)
.First().Selected;
更难以遵循,但基本上做同样的事情。
正如Dominic在下面提到的,如果您使用SingleOrDefault/Single
代替FirstOrDefault/First
,如果您在ListA
中找到两个具有相同ID
的项目,则会收到例外情况 - 这可能是您要介绍的支票。
(是更好/更有效的方法,但正如你所说,你想要修复这种的做法,而不是采用完全不同的方式。)
答案 1 :(得分:2)
这个怎么样?
var query = from b in ListB
join a in ListA
on b.ID equals a.ID into g
from r in g.DefaultIfEmpty(b)
select new Item { ID = b.ID, Selected = r.Selected };