LINQ一般查询到的结果是IEnumerable<T>集合类型,想要从中取出单一的元素,可以使用Single、First、Last、ElementAt等方法,以及它们带有OrDefault的形式。
Single返回序列中的唯一元素,First、Last返回第一个、最后一个元素。
对比一下:
方法 | 序列为null时 | 序列不包含任何元素时 | 序列只包含一个元素时 | 序列包含多个元素时 |
Single | 引发异常 | 引发异常 | 返回该元素 | 引发异常 |
SingleOrDefault | 引发异常 | 返回default(TSource) | 返回该元素 | 引发异常 |
First | 引发异常 | 引发异常 | 返回该元素 | 返回第一个元素 |
FirstOrDefault | 引发异常 | 返回default(TSource) | 返回该元素 | 返回第一个元素 |
Last | 引发异常 | 引发异常 | 返回该元素 | 返回最后一个元素 |
LastOrDefault | 引发异常 | 返回default(TSource) | 返回该元素 | 返回最后一个元素 |
Single、SingleOrDefault可以用来确保序列中不存在多个元素。
SingleOrDefault可以用来检验序列中是否包含有元素。引用类型的默认值default(T)为null,表示在序列中没有找到元素。
下面来看一下Single、SingleOrDefault的实际使用。
1、用户登录:
public static User QueryUser(string code, string password) { using (SQLiteConnection conn = new SQLiteConnection(connectionString)) { string sql = "select * from User where Code = @Code and Password = @Password"; var param = new { Code = code, Password = password }; return conn.Query<User>(sql, param).SingleOrDefault(); } }
在用户表中,Code是唯一的,如果查询出多个满足条件的用户,要抛异常;如果没有查询到用户,返回null做进一步判断处理。
2、将用户表绑定到DataGrid后,单选一个用户:
IEnumerable<User> query = (dataGrid.ItemsSource as IEnumerable<User>) .Where(user => user.IsChecked); if (query.Count() == 0) { MessageBox.Show("没有选中"); return; } if (query.Count() > 1) { MessageBox.Show("不能多选"); return; } User user = query.Single();
因为在之前判断过序列的元素数量,所以调用Single取出用户就不会有问题了。