我发现自己写了很多类似这样的代码来选择一个匹配的项
var item = (from x in Items where x.Id == 123 select x).First();
有没有一种更干净的方法来做,或者这是我将要得到的简洁的方法?编辑:应该说“使用linq语法的更干净的方法”。我已经知道了lambda语法,而且开始看起来这实际上是唯一的方法。不过我确实得到了一些有用的信息,所以感谢每个回复的人。
kognpnkq1#
根据您对linq查询语法的喜欢程度,您可以直接使用扩展方法,如下所示:
var item = Items.First(i => i.Id == 123);
如果你不想在列表为空时抛出错误,可以使用FirstOrDefault,它返回元素类型的默认值(null用于引用类型):
FirstOrDefault
null
var item = Items.FirstOrDefault(i => i.Id == 123); if (item != null) { // found it }
也可以使用Single()和SingleOrDefault(),但是如果你从数据库或者已经保证唯一性的东西阅读,我不会打扰,因为它必须扫描列表,看看是否有任何重复和抛出。First()和FirstOrDefault()在第一个匹配时停止,所以它们更有效。在First()和Single()系列中,以下是它们抛出的代码:
Single()
SingleOrDefault()
First()
FirstOrDefault()
yduiuuwa2#
FirstOrDefault或SingleOrDefault可能会很有用,这取决于您的场景,以及您是希望处理零个匹配还是多个匹配:第一个或默认:返回序列的第一个元素,如果未找到任何元素,则返回默认值。单一或默认:返回序列的唯一元素,如果序列为空,则返回默认值;如果序列中有多个元素,此方法将引发异常我不知道这在linq 'from'查询中是如何工作的,但在lambda语法中看起来像这样:
var item1 = Items.FirstOrDefault(x => x.Id == 123); var item2 = Items.SingleOrDefault(x => x.Id == 123);
kpbpu0083#
只是为了让某些人的生活更轻松,使用lambda表达式的linq查询
(from x in Items where x.Id == 123 select x).FirstOrDefault();
会导致SQL查询中包含select top (1)。
select top (1)
cfh9epnr4#
以下是首选方法:
var item = Items.SingleOrDefault(x => x.Id == 123);
或者
var item = Items.Single(x => x.Id == 123);
igsr9ssn5#
最好能浓缩成这样。var item = Items.First(x => x.Id == 123);您的查询当前正在收集可枚举对象中的所有结果(可能不止一个),然后从 * 那个 * 集中获取第一个结果,这做了很多不必要的工作。Single/SingleOrDefault是有价值的,但只有当您希望遍历整个集合并验证匹配项是否唯一时,才需要选择该匹配项。First/FirstOrDefault将只接受第一个匹配项并离开,而不管实际存在多少重复项。
var item = Items.First(x => x.Id == 123);
g0czyy6m6#
您可以使用扩展方法语法:
var item = Items.Select(x => x.Id == 123).FirstOrDefault();
除此之外,如果不编写自己的专用“First”和“FirstOrDefault”扩展方法,我不确定还能得到多少更简洁的结果。
iqjalb3h7#
我来告诉你什么对我有效:
int id = int.Parse(insertItem.OwnerTableView.DataKeyValues[insertItem.ItemIndex]["id_usuario"].ToString()); var query = user.First(x => x.id_usuario == id); tbUsername.Text = query.username; tbEmail.Text = query.email; tbPassword.Text = query.password;
我的id是我想查询的行,在这个例子中我从radGrid中得到它,然后我用它来查询,但是这个查询返回一行,然后你可以把你从查询中得到的值赋给textbox,或者任何东西,我必须把那些赋给textbox。
mgdq6dx18#
如果您没有该表的特定ID,并且需要匹配多个条件以获得唯一值,我们可以执行以下操作:
var item = Items. .Where(x => x.Name== "Name you are looking for") .Where(x => x.Status == 1) .FirstOrDefault();
如果条件匹配,将返回Items中的第一个元素。如果您确定Items包含唯一元素,则可以使用FirstOrDefault(),因为这样会更快。我们也可以使用SingleOrDefault()或者FirstOrDefault(),但是在返回值之前,它会继续寻找第二个相同的元素。如果我们查询一个大的数据库表,这可能会造成一些延迟。如果我们确定列表是唯一的,最好使用FirstOrDefault。
Items
8条答案
按热度按时间kognpnkq1#
根据您对linq查询语法的喜欢程度,您可以直接使用扩展方法,如下所示:
如果你不想在列表为空时抛出错误,可以使用
FirstOrDefault
,它返回元素类型的默认值(null
用于引用类型):也可以使用
Single()
和SingleOrDefault()
,但是如果你从数据库或者已经保证唯一性的东西阅读,我不会打扰,因为它必须扫描列表,看看是否有任何重复和抛出。First()
和FirstOrDefault()
在第一个匹配时停止,所以它们更有效。在
First()
和Single()
系列中,以下是它们抛出的代码:First()
-如果为空/未找到则抛出,如果重复则不抛出FirstOrDefault()
-如果为空/未找到则返回默认值,如果重复则不抛出Single()
-如果为空/未找到则抛出,如果存在重复则抛出SingleOrDefault()
-如果为空/未找到则返回默认值,如果存在重复则抛出yduiuuwa2#
FirstOrDefault或SingleOrDefault可能会很有用,这取决于您的场景,以及您是希望处理零个匹配还是多个匹配:
第一个或默认:返回序列的第一个元素,如果未找到任何元素,则返回默认值。
单一或默认:返回序列的唯一元素,如果序列为空,则返回默认值;如果序列中有多个元素,此方法将引发异常
我不知道这在linq 'from'查询中是如何工作的,但在lambda语法中看起来像这样:
kpbpu0083#
只是为了让某些人的生活更轻松,使用lambda表达式的linq查询
会导致SQL查询中包含
select top (1)
。cfh9epnr4#
以下是首选方法:
或者
igsr9ssn5#
最好能浓缩成这样。
var item = Items.First(x => x.Id == 123);
您的查询当前正在收集可枚举对象中的所有结果(可能不止一个),然后从 * 那个 * 集中获取第一个结果,这做了很多不必要的工作。
Single/SingleOrDefault是有价值的,但只有当您希望遍历整个集合并验证匹配项是否唯一时,才需要选择该匹配项。First/FirstOrDefault将只接受第一个匹配项并离开,而不管实际存在多少重复项。
g0czyy6m6#
您可以使用扩展方法语法:
除此之外,如果不编写自己的专用“First”和“FirstOrDefault”扩展方法,我不确定还能得到多少更简洁的结果。
iqjalb3h7#
我来告诉你什么对我有效:
我的id是我想查询的行,在这个例子中我从radGrid中得到它,然后我用它来查询,但是这个查询返回一行,然后你可以把你从查询中得到的值赋给textbox,或者任何东西,我必须把那些赋给textbox。
mgdq6dx18#
如果您没有该表的特定ID,并且需要匹配多个条件以获得唯一值,我们可以执行以下操作:
如果条件匹配,将返回
Items
中的第一个元素。如果您确定Items
包含唯一元素,则可以使用FirstOrDefault(),因为这样会更快。我们也可以使用
SingleOrDefault()
或者FirstOrDefault()
,但是在返回值之前,它会继续寻找第二个相同的元素。如果我们查询一个大的数据库表,这可能会造成一些延迟。如果我们确定列表是唯一的,最好使用FirstOrDefault
。