linq first中First和Single 的区别

C#, linq to sql, 为嘛single生成的sql 是top (2)而不是top (1) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
Sponsored by
国内领先的实时后端云野狗 API 可用于开发即时聊天、网络游戏、实时定位等实时场景传输快!响应快!入门快!
Promoted by
C#, linq to sql, 为嘛single生成的sql 是top (2)而不是top (1)
19:46:38 +08:00 · 2387 次点击
SELECT TOP (2)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[Url] AS [Url],
[Extent1].[ParentId] AS [ParentId]
FROM [dbo].[MenuItem] AS [Extent1]
WHERE [Extent1].[ParentId] IS NULL
10 回复 &| &直到
08:00:00 +08:00
& & 19:48:32 +08:00
好吧,single 如果结果多于2个就抛出异常
& & 18:57:15 +08:00
生成的sql应该是:
SELECT [t0].[id] as [id]
FROM [dbo].[table] as [t0]
WHERE [t0].[id] IS NULl
这样的,没有TOP语句;
Single扩展方法Returns the only element of a sequence that satisfies a specified condition, and throws an exception if more than one such element exists.
& & 19:35:16 +08:00
& & 23:34:15 +08:00
@ 我用linqpad实验的结果显示,Single生成的sql是没有Top的;First会产生Top语句;不过/questions/8829314/why-does-single-linq-extension-method-create-a-query-select-top2 确实是如你所说的情况。
也许是Linqpad显示的sql有问题?
明天去看看Single源码去
& & 00:12:23 +08:00
是要检查是不是多于1个吧。这个时候返回top 2不是很合理?
& & 09:28:22 +08:00
@ 你要用sql server profiler去看
& & 09:29:09 +08:00
@ single 是取唯一的一个,first是取多个中的第一个,所以single要做多于1的判断
& & 10:49:56 +08:00
@ 很奇怪啊,我确实用sql profiler看了,是没有top的。。。
难道跟Linq版本有关,我是4.0;
C#查询是:
var ret = App_Case_Alls.Single(c =& c.Case_type == 1);
Console.Write(ret);
sql profilerie截到的sql是:
exec sp_executesql N'SELECT [t0].[case_id] AS [Case_id], [t0].[case_type] AS [Case_type], [t0].[req_no] AS [Req_no]
FROM [app_Case_All] AS [t0]
WHERE [t0].[case_type] = @',N'@p0 int',@p0=1
& & 15:21:34 +08:00
@ 我说的就是这个意思。。。。
& & 16:18:09 +08:00
@ 终于弄清楚了,用Entity Framework的Linq查询Single,确实生成的sql是TOP(2); 但用Linq-to-Sql的话,Single是不会有产生TOP语句的;我的实验都是直接用Linq-to-sql的,所以才产生困扰。see
& · & 1666 人在线 & 最高记录 2011 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.3 · 40ms · UTC 01:13 · PVG 09:13 · LAX 18:13 · JFK 21:13? Do have faith in what you're doing.您的位置: >
.NET中First,FirstOrDefault,Single,SingleOrDefault的区别
学习标签:
本文导读:Linq中的 First 和 Single 在实际工作中会经常看到,First 是取列表中的第一个元素,如果没有赋默认值则用FirstOrDefault,Single是取到唯一的元素,如果没有赋默认值则用SingleOrDefault,下面介绍它们的区别
取序列中满足条件的第一个元素,如果没有元素满足条件,则抛出异常&
二、FirstOrDefault
取序列中满足条件的第一个元素,如果没有元素满足条件,则返回默认值(对于可以为null的对象,默认值为null,对于不能为null的对象,如int,默认值为0)
三、Single
返回序列中的唯一一条记录,如果没有或返回多条,则引发异常。
四、SingleOrDefault
返回序列中的唯一一条记录,如果序列中不包含任何记录,则返回默认值,如果返回多条,则引发异常。&
五、使用场合
1、当确信序列中一定有满足条件的元素时,使用First方法,取到元素后,无需判断是否为null&
2、当序列中可能找不到满足条件的元素时,使用FirstOrDefault方法,然后,一定要对返回值是否为null,进行不同的处理
C# 代码 &&复制
using System.Collections.G
using System.L
using System.T
using System.Threading.T
namespace SingleOrDefaultDemo
class Program
static void Main(string[] args)
var lst = new List&int& ...{ <span style="color: #, <span style="color: #, <span style="color: #0, <span style="color: #, <span style="color: #, <span style="color: #, <span style="color: # };
//输出结果:10
Console.WriteLine(&First:{0}&, lst.First());
//输出结果:10
Console.WriteLine(&FirstOrDefault:{0}&, lst.FirstOrDefault());
//输出结果:100(注:因为这里的First是按List&int&的索引来取第一个符合条件的元素,所以结果是100,而不是按从小到大的顺序)
Console.WriteLine(&First:{0}&, lst.First(x =& x & <span style="color: #));
//输出结果:100(同上First)
Console.WriteLine(&FirstOrDefault:{0}&, lst.FirstOrDefault(x =& x & <span style="color: #));
// 抛出异常:序列包含一个以上的元素
//Console.WriteLine(&Single:{0}&, lst.Single());
// 抛出异常:序列包含一个以上的元素
//Console.WriteLine(&SingleOrDefault:{0}&, lst.SingleOrDefault());
//抛出异常:序列不包含任何匹配元素
//Console.WriteLine(&Single:{0}&, lst.Single(x =& x & 100));
//输出结果:0
Console.WriteLine(&SingleOrDefault:{0}&, lst.SingleOrDefault(x =& x & <span style="color: #0));
Console.WriteLine(&Press any key to quit...&);
Console.ReadKey();
您可能感兴趣
一月好评排行榜Are you Sure?
Project Description
linq.js - LINQ for JavaScript
implement all .NET 4.0 methods and many extra methods (inspiration from , , Haskell, Ruby, etc...)
complete lazy evaluation full IntelliSense support for VisualStudio two versions - linq.js and jquery.linq.js (jQuery plugin) support Windows Script Host binding for Reactive Extensions for JavaScript(RxJS) and IntelliSense Generator -& see
NuGet install support(,
90 Methods
Aggregate, All, Alternate, Any, Average, BufferWithCount, CascadeBreadthFirst, CascadeDepthFirst, Catch, Choice, Concat,
Contains, Count, Cycle, DefaultIfEmpty, Distinct, Do, ElementAt, ElementAtOrDefault, Empty, Except, Finally, First, FirstOrDefault,
Flatten, ForEach, Force, From, Generate, GetEnumerator, GroupBy, GroupJoin, IndexOf, Insert, Intersect, Join, Last, LastIndexOf,
LastOrDefault, Let, Matches, Max, MaxBy, MemoizeAll, Min, MinBy, OfType, OrderBy, OrderByDescending, Pairwise, PartitionBy,
Range, RangeDown, RangeTo, Repeat, RepeatWithFinalize, Return, Reverse, Scan, Select, SelectMany, SequenceEqual, Share, Shuffle,
Single, SingleOrDefault, Skip, SkipWhile, Sum, Take, TakeExceptLast, TakeFromLast, TakeWhile, ThenBy, ThenByDescending, ToArray,
ToDictionary, ToInfinity,ToJSON, ToLookup, ToNegativeInfinity, ToObject, ToString, Trace, Unfold, Union, Where, Write, WriteLine, Zip
see details -
Starting linq.js ver.3.0.0-beta!()
or NuGet Install-Package linq.js -Pre, linq.js-jQuery -Pre, linq.js-RxJS -Pre, linq.js-QUnit -Pre
Now TypeScript Generics(0.9) support!
Please try it! and give me a feedback!
Query objects or json
sample from /statuses/public_timeline.json
var jsonArray = [
{ &user&: { &id&: 100, &screen_name&: &d_linq& }, &text&: &to objects& },
{ &user&: { &id&: 130, &screen_name&: &c_bill& }, &text&: &g& },
{ &user&: { &id&: 155, &screen_name&: &b_mskk& }, &text&: &kabushiki kaisha& },
{ &user&: { &id&: 301, &screen_name&: &a_xbox& }, &text&: &halo reach& }
// [&b_mskk:kabushiki kaisha&, &c_bill:g&, &d_linq:to objects&]
var queryResult = Enumerable.From(jsonArray)
.Where(function (x) { return x.user.id & 200 })
.OrderBy(function (x) { return x.user.screen_name })
.Select(function (x) { return x.user.screen_name &#43; &#39;:&#39; &#43; x.text })
.ToArray();
// shortcut! string lambda selector
var queryResult2 = Enumerable.From(jsonArray)
.Where(&$.user.id & 200&)
.OrderBy(&$.user.screen_name&)
.Select(&$.user.screen_name &#43; &#39;:&#39; &#43; $.text&)
.ToArray();
High compatibility with C# Linq
// C# LINQ (delegate)
Enumerable.Range(1, 10)
.Where(delegate(int i) { return i % 3 == 0; })
.Select(delegate(int i) { return i * 10; });
// linq.js - anonymous function
Enumerable.Range(1, 10)
.Where(function(i) { return i % 3 == 0; })
.Select(function(i) { return i * 10; });
// C# LINQ (lambda)
Enumerable.Range(1, 10).Where(i =& i % 3 == 0).Select(i =& i * 10);
// linq.js - lambda expression
Enumerable.Range(1, 10).Where(&i =& i % 3 == 0&).Select(&i =& i * 10&);
// $ is default iterator variable like Scala&#39;s &_& or Groovy&#39;s &it&
Enumerable.Range(1, 10).Where(&$ % 3 == 0&).Select(&$ * 10&);
// && is shorthand of &x =& x& (identity function)
Enumerable.Range(4, 7).Join(Enumerable.Range(8, 5), &&, &&, &outer,inner=&outer*inner&);
// Enumerable.From is wrap from primitive array, string(to charArray), object(to KeyValuePair[]) etc..
var array = [100, 200, 30, 40, 500, 40, 200];
var ex1 = Enumerable.From(array).Distinct().ToArray(); // [100, 200, 30, 40, 500]
var ex2 = Enumerable.From(&foobar&).ToArray(); // [&f&, &o&, &o&, &b&, &a&, &r&];
var ex3 = Enumerable.From({foo:10, bar:20}).ToArray(); // [{Key:&foo&,Value:10}, {Key:&bar&,Value:20}]
// C# - AnonymousType
array.Select((val, i) =& new { Value = val, Index = i });
// linq.js - object literal
Enumerable.From(array).Select(&val,i=&{Value:val, Index:i}&)
jQuery plugin version
// $.Enumerable
$.Enumerable.Range(1, 10).Where(&$%2==0&).ForEach(&alert($)&);
// TojQuery - Enumerable to jQuery
$.Enumerable.Range(1, 10)
.Select(function (i) { return $(&&option&&).text(i)[0] })
.TojQuery()
.appendTo(&#select1&);
// toEnumerable - jQuery to Enumerable
var sum = $(&#select1&).children()
.toEnumerable()
.Select(&parseInt($.text())&)
.Sum(); // 55
IntelliSense vsdoc
video - using with Visual Studio 2010
video - how to debug linq.js
with Windows Script Host
// get folder name and file name...
var dir = WScript.CreateObject(&Scripting.FileSystemObject&).GetFolder(&C:\\&);
// normally
var itemNames = [];
for (var e = new Enumerator(dir.SubFolders); !e.atEnd(); e.moveNext())
itemNames.push(e.item().Name);
for (var e = new Enumerator(dir.Files); !e.atEnd(); e.moveNext())
itemNames.push(e.item().Name);
// linq.js
var itemNames2 = Enumerable.From(dir.SubFolders).Concat(dir.Files).Select(&$.Name&).ToArray();
Last edited
by , version 48
ver 2.2.0.2
31 ratings
Most Helpful Reviews
&&&&&The library works nicely, very useful, I&#39;ve been using it a lot. &#10;&#10;It would be nice to see an update since the last stable release w...
&&&&&I wish I would have found this sooner&#33;
Simply awesome&#33;Linq中的 First 和 Single 在实际工作中会经常看到,从字面意思上很容易明白,一个是取列表中的第一个元素,一个是取到唯一的元素。如果你想再进一步的了解,可以读读本文。
下文参考翻译自:
First() - 返回序列中的第一个元素
事实上这个方法有四种选择:
返回序列中的第一个,如果没有元素存在就抛出异常 InvalidOperationException.
First(Predicate&TSource&)
基于你提供的条件返回序列中的第一个,如果没有元素存在就抛出异常 InvalidOperationException.
FirstOrDefault()
返回序列中的第一个,如果没有元素存在就返回默认的元素default(TSource).
FirstOrDefault(Predicate&TSource&)
基于你提供的条件返回序列中的第一个,如果没有元素存在就返回默认的元素default(TSource).
First的核心思想是如果序列中存在一个以上元素的时候,就返回第一个。这也意味着当发现第一个元素的时候,被调用的这个方法就立刻退出了不会再去遍历寻找剩下的元素了。
举例看看,定义一个类:
& public sealed class Employee
public long Id { get; set; }
public string Name { get; set; }
public double Salary { get; set; }
给他一些初始化的列表:有空的,一个元素的,多个元素的
var noEmployeeList = new List&Employee&();
// 一个元素
var oneEmployeeList = new List&Employee&
new Employee { Id = 55, Name = "Sussie Queue", Salary = 60000.50 }
// 多个元素
var employees = new List&Employee&
new Employee { Id = 1, Name = "Jim Smith", Salary = 12345.50 },
new Employee { Id = 7, Name = "Jane Doe", Salary = 31234.50 },
new Employee { Id = 9, Name = "John Doe", Salary = 13923.99 },
new Employee { Id = 13, Name = "Jim Smith", Salary = 30123.49 },
// ... etc ...
好,当我们使用First的时候,他们会有什么结果呢?
&var first = employees.First();
var firstJohn = employees.First(e =& e.Name.StartsWith("John"));
var firstDoe = employee.First(e =& e.Name.EndsWith("Doe"));
另外请注意在下面的情况下会抛出异常:
&var empty = noEmployees.First();
var noMatch = employees.First(e =& e.Id == 20);
最后,当我们使用带有Default的方法时,下面的情况会返回空值而不是抛出异常:
&var empty = noEmployees.FirstOrDefault();
var noMatch = employees.FirstOrDefault(e =& e.Id == 20);
Single() & 有且仅有一个
&像First一样,Single 也有四种表现形式:
返回序列中的唯一的元素,如果没有元素存在就抛出异常 InvalidOperationException, 如果多于一个,也抛出异常InvalidOperationException.
Single(Predicate&TSource&)
基于你提供的条件返回序列中的唯一的元素,如果没有元素存在就抛出异常 InvalidOperationException, 如果多于一个,抛出异常InvalidOperationException.& SingleOrDefault()
SingleOrDefault()
返回序列中的唯一的元素,如果没有元素存在就返回默认的元素default(TSource), 如果多于一个,抛出异常InvalidOperationException.
SingleOrDefault(Predicate&TSource&)
基于你提供的条件返回序列中的唯一的元素,如果没有元素存在就返回默认的元素default(TSource), 如果多于一个,抛出异常InvalidOperationException.
请注意,关键的区别主要在这里: 如果有一个以上的元素,这个家族的方法会永远抛出InvalidOperationException异常。& 还要注意,这意味着,即使Single 方法得到了一个匹配的元素,它仍然有可能要扫描其余的枚举。 这可以使 Single 效率要低一点。
下面一些例子返回什么呢?
&var oneAndOnly = oneEmployeeList.Single();
var throwsOnEmpty = noEmployeeList.Single();
var throwsOnMultiple = employeeList.Single();
从下面的例子,我们看到Single 和 First 的相似性, 不同的在于满足结果的序列多于一个元素的情况
&// 得到 ID == 7 的唯一元素
var oneAndOnlyMatch = oneEmployeeList.Single(e =& e.Id == 7);
// 抛出异常
var throwsOnNoMatches = noEmployeeList.Single(e =& e.Id == 999);
// 抛出异常
var throwsOnMultipleMatches = employeeList.Single(e =& e.Name.EndsWith("Doe"));
// 返回一个null的元素.
var defaultsOnEmpty = noEmployeeList.SingleOrDefault();
// 返回一个null的元素.
var defaultsOnNoMatch = noEmployeeList.SingleOrDefault(e =& e.Id == 999);
First 和 Single 都有一个避免当没有元素满足要求而抛出异常的选择,当你不确定想要获取的元素是否存在的时候,可以用&OrDefault(), 因为 null 可以很好的表示&找到不&。
当你不在乎是否有重复项目或者不可能有重复元素存在的时候,可以使用First; 当你想要核实是否有重复元素存在的时候当然就选择Single。
谢谢你阅读本文,更多.NET话题请到:
阅读(...) 评论()&int&otherClassID&=&ctx.voteMasters.Where(v&=&&v.ID&!=&currentClassid&&&&v.TypeID&==&100).Select(v&=&&v.ID).Single();
single()不是只获取一个元素吗?怎么会有多个呢?
当然数据库中typeid=100的有很多个
不是single()=take(1)吗?
回复讨论(解决方案)
错误:序列包含一个以上的元素&
Single():&返回序列中满足指定条件的唯一元素;如果有多个这样的元素存在,则会引发异常。
First():返回序列中满足指定条件的第一个元素。&有多个符合条件&也只返回第一个
为了避免程序异常
不建议使用single和first方法&
建议使用singleordefault()&和firstordefault()代替之
first&()倒是可以理解成&take(1)
嗯的&懒人不看MSDN&就是这样&呵呵}

我要回帖

更多关于 linq find first 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信