1

我有以下课程:

public partial class Content
{
    public int ContentId { get; set; }
    public int ContentTypeId { get; set; }
    public string Title { get; set; }
    public string Text { get; set; }

    public int SubjectId { get; set; }
    public virtual Subject Subject { get; set; }
}

我知道我可以使用这样的 Linq 查询:

.Where(a => a.SubjectId == subjectId)

但是我怎样才能做到,所以还有另一个条件

.Where(a => a.ContentTypeId == contentTypId) 

有没有一种方法可以将它们合并成一个,或者应该将它们保持为两个?

4

3 回答 3

6

仅使用一个Where包含每个条件的子句:

.Where(a => a.SubjectId == subjectId && a.ContentTypeId == contentTypId)

或两个Where子句,每个子句处理一个条件:

.Where(a => a.SubjectId == subjectId)
.Where(a => a.ContentTypeId == contentTypId)

是等效的,因为 LINQ 查询执行被推迟到结果调用。

于 2013-06-20T09:28:09.037 回答
3

你也可以这样做:

.Where(a => a.SubjectId == subjectId).Where(a => a.ContentTypeId == contentTypId) 

这对于在代码中动态构建查询很有用。

于 2013-06-20T09:32:30.017 回答
1

omer schleifer 的回答让我对案例进行了基准测试,并最终检查了创建的 IL 以查看链接子句中是否存在性能损失..

让我们看看下面的例子:

var numbers = new List<int>() { 1, 2 ,3,4,5,6,7,8,9,10};
IEnumerable<int> query = numbers.Where(x=> x>2 && x<5);

导致以下 IL:

IL_0001:  newobj      System.Collections.Generic.List<System.Int32>..ctor
IL_0006:  stloc.2     // <>g__initLocal0
IL_0007:  ldloc.2     // <>g__initLocal0
...
...
...    
IL_0059:  ldloc.2     // <>g__initLocal0
IL_005A:  stloc.0     // numbers
IL_005B:  ldloc.0     // numbers
IL_005C:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate2
IL_0061:  brtrue.s    IL_0076
IL_0063:  ldnull      
IL_0064:  ldftn       b__1
IL_006A:  newobj      System.Func<System.Int32,System.Boolean>..ctor
IL_006F:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate2
IL_0074:  br.s        IL_0076
IL_0076:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate2
IL_007B:  call        System.Linq.Enumerable.Where
IL_0080:  stloc.1     // query
IL_0081:  ldloc.1     // query    

b__1:
IL_0000:  ldarg.0     
IL_0001:  ldc.i4.2    
IL_0002:  ble.s       IL_000A
IL_0004:  ldarg.0     
IL_0005:  ldc.i4.5    
IL_0006:  clt         
IL_0008:  br.s        IL_000B
IL_000A:  ldc.i4.0    
IL_000B:  stloc.0     // CS$1$0000
IL_000C:  br.s        IL_000E
IL_000E:  ldloc.0     // CS$1$0000
IL_000F:  ret  

//链接示例:

var numbers = new List<int>() { 1, 2 ,3,4,5,6,7,8,9,10};
IEnumerable<int> query = numbers.Where(x=> x>2).Where(x => x<5);

//导致以下IL:

IL_0001:  newobj      System.Collections.Generic.List<System.Int32>..ctor
IL_0006:  stloc.2     // <>g__initLocal0
IL_0007:  ldloc.2     // <>g__initLocal0
IL_0008:  ldc.i4.1    
...
...
...
IL_0058:  nop         
IL_0059:  ldloc.2     // <>g__initLocal0
IL_005A:  stloc.0     // numbers
IL_005B:  ldloc.0     // numbers
IL_005C:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate3
IL_0061:  brtrue.s    IL_0076
IL_0063:  ldnull      
IL_0064:  ldftn       b__1
IL_006A:  newobj      System.Func<System.Int32,System.Boolean>..ctor
IL_006F:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate3
IL_0074:  br.s        IL_0076
IL_0076:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate3
IL_007B:  call        System.Linq.Enumerable.Where  <--------first where call
IL_0080:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate4
IL_0085:  brtrue.s    IL_009A
IL_0087:  ldnull      
IL_0088:  ldftn       b__2
IL_008E:  newobj      System.Func<System.Int32,System.Boolean>..ctor
IL_0093:  stsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate4
IL_0098:  br.s        IL_009A
IL_009A:  ldsfld      UserQuery.CS$<>9__CachedAnonymousMethodDelegate4
IL_009F:  call        System.Linq.Enumerable.Where  <--------second where call
IL_00A4:  stloc.1     // query
IL_00A5:  ldloc.1     // query

b__1:
IL_0000:  ldarg.0     
IL_0001:  ldc.i4.2    
IL_0002:  cgt         
IL_0004:  stloc.0     // CS$1$0000
IL_0005:  br.s        IL_0007
IL_0007:  ldloc.0     // CS$1$0000
IL_0008:  ret         

b__2:
IL_0000:  ldarg.0     
IL_0001:  ldc.i4.5    
IL_0002:  clt         
IL_0004:  stloc.0     // CS$1$0000
IL_0005:  br.s        IL_0007
IL_0007:  ldloc.0     // CS$1$0000
IL_0008:  ret

该示例显示有 to where 调用,第二个接收第一个结果作为输入。
因此,Linq to Objects性能会受到影响。
性能恶化的程度取决于数据量和 where 子句的顺序,第一个子句过滤的越多,下一个子句必须操作的越少,依此类推……在我看来,在大多数情况下性能影响不会很大。

In Linq to SQLChaining Where 子句对性能没有影响,因为将创建相同的 SQL。

于 2013-06-25T10:06:41.843 回答