Linq查询“where [column] in(values of values)”为每个值返回单个值?

时间:2016-11-08 11:06:42

标签: c# linq

假设我们有这个LinQ代码(在LinqPad中):

List<string> list = new List<string>();
list.Add("1611080010");
list.Add("1611080011");
list.Add("WRONGID");

var result = Orders.AsQueryable().Where(y => list.Contains(y.Id));
// And yes my Ids are string for this sample
result.Dump(); // To display the result in LinqPad
result.Count(); // equal 2

是否可以改进此查询以强制系统为每个list元素返回一个元素或抛出异常?所以如果我的列表中有3个值,我的结果中应该有3个值?

3 个答案:

答案 0 :(得分:3)

关于你的问题:是否可以改进此查询以强制系统为每个list元素返回一个元素或抛出异常:

var result = Orders.AsQueryable().SingleOrDefault(y => list.Contains(y.Id));

SingleOrDefault

  

返回序列的唯一元素,如果是,则返回默认值   序列是空的;如果有更多,此方法会抛出异常   比序列中的一个元素。

答案 1 :(得分:1)

您可以使用下面的任何一个

每当您使用SingleOrDefault时,您都清楚地声明查询最多只能产生一个结果。另一方面,当使用FirstOrDefault时,查询可以返回任意数量的结果,但是您声明只需要第一个结果。

我个人觉得语义非常不同,使用适当的语义,取决于预期的结果,提高了可读性。

var result = Orders.AsQueryable().SingleOrDefault(y => list.Contains(y.Id));

var result = Orders.AsQueryable()..FirstOrDefault(y => list.Contains(y.Id));

答案 2 :(得分:1)

如果我正确理解了您的问题,您希望从Orders返回一个对象,其中对象的ID等于您list中的ID以及list中的ID是否出现在Orders对象中的异常应该抛出。

要实现这一点,你可以这样做:

var result = list.Select(id => Orders.AsQueryable().First(y => y.Id == id)).ToList();

如果来自list的ID在Orders对象中不匹配,则会抛出异常。如果找到所有ID,则result将包含与list中的ID相同数量的元素。

另一种选择是使用:

var result = list.Select(id => Orders.AsQueryable().FirstOrDefault(y => y.Id == id)).ToList();

这不会引发错误,但它总会返回与list中的ID相同数量的元素。找不到的ID会有一个null条目。