C# 在带有实体框架的SQL中选择直到

C# 在带有实体框架的SQL中选择直到,c#,sql,linq,entity-framework,tsql,C#,Sql,Linq,Entity Framework,Tsql,我想选择行,直到找到某个数字Id。如果我的数据是按Id排序的,那么问题很容易解决 Id Name ----------- 1 Bob 2 Eve 3 Alice 4 Michael 5 Anne 6 Mike 要在找到Id 4之前获取所有项,以下SQL语句就足够了: SELECT * FROM Users WHERE Id <= 4 要定义的语句的输出应为: Id Name ----------- 3 Alice 5

我想选择行,直到找到某个数字Id。如果我的数据是按Id排序的,那么问题很容易解决

Id    Name
-----------
1     Bob
2     Eve
3     Alice
4     Michael
5     Anne
6     Mike
要在找到Id 4之前获取所有项,以下SQL语句就足够了:

SELECT * FROM Users WHERE Id <= 4
要定义的语句的输出应为:

Id    Name
-----------
3     Alice
5     Anne
1     Bob
2     Eve
4     Michael
编辑1:

在下面的语句中,输出几乎是我所需要的,但缺少Id为4的项

queryable.OrderBy(o => o.Name).TakeWhile(o => o.Id != 4);

Id    Name
-----------
3     Alice
5     Anne
1     Bob
2     Eve
是否也可以包含Id为4的项目

编辑2:

现在我将采用这种方法:

queryable.OrderBy(o => o.Name).TakeWhile(o => o.Id != 4).Union(queryable.Where(o => o.Id == 4))
var result = Users.TakeWhile(u=>u.Id!=4)
                  .Union(Users.SkipWhile(u=>u.Id!=4).Take(1));
由于Id是唯一的,UNION语句应该没有问题。但我不确定这句话是否最有效

var result = Users.TakeWhile((u,i)=> i == 0 || Users.ElementAt(i-1).Id != 4);
另一种方法:

queryable.OrderBy(o => o.Name).TakeWhile(o => o.Id != 4).Union(queryable.Where(o => o.Id == 4))
var result = Users.TakeWhile(u=>u.Id!=4)
                  .Union(Users.SkipWhile(u=>u.Id!=4).Take(1));
另一种方法:

queryable.OrderBy(o => o.Name).TakeWhile(o => o.Id != 4).Union(queryable.Where(o => o.Id == 4))
var result = Users.TakeWhile(u=>u.Id!=4)
                  .Union(Users.SkipWhile(u=>u.Id!=4).Take(1));

无论顺序如何,select语句仍将返回Id小于或等于4的所有记录。我知道这一点。我的问题是找到一个考虑排序的语句。无论排序如何,select语句仍将返回Id小于或等于4的所有记录。我知道这一点。我的问题是找到一个考虑顺序的语句。该语句返回1项。我认为采取(1)是没有必要的。如果我删除Take(1),输出几乎就是我需要的,但是缺少Id为4的项。这似乎可行,但我不太确定为什么。你能用几句话解释一下吗?:)@Moo重点是使用
ElementAt
引用当前迭代中的上一个元素,在您的示例中,在
6
元素处,上一个元素是
4
,因此它停止在那里并丢弃元素
6
,之前返回的所有元素都是从开始到
4
的元素。谢谢,我喜欢这种方法!您如何看待“queryable.OrderBy(o=>o.Name).TakeWhile(o=>o.Id!=4).Union(queryable.Where(o=>o.Id==4))”。哪个语句更有效?@Moo我不认为它更好,它确实使用了2个查询,您可能还有更多的ID
4
,第二个
,其中
将返回一个项目集合(而不仅仅是1个项目),因此它是错误的。此语句返回1个项目。我认为采取(1)是没有必要的。如果我删除Take(1),输出几乎就是我需要的,但是缺少Id为4的项。这似乎可行,但我不太确定为什么。你能用几句话解释一下吗?:)@Moo重点是使用
ElementAt
引用当前迭代中的上一个元素,在您的示例中,在
6
元素处,上一个元素是
4
,因此它停止在那里并丢弃元素
6
,之前返回的所有元素都是从开始到
4
的元素。谢谢,我喜欢这种方法!您如何看待“queryable.OrderBy(o=>o.Name).TakeWhile(o=>o.Id!=4).Union(queryable.Where(o=>o.Id==4))”。哪个语句更有效?@Moo我不认为它更好,它确实使用了2个查询,您也可能有更多的ID
4
,第二个
,其中
将返回一个项目集合(而不仅仅是一个项目),因此它是错误的。