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) 

これらを1つに結合する方法はありますか、または2つのままにする必要がありますか?

4

3 に答える 3

6

Whereすべての条件を含む句を1 つだけ使用する:

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

またはWhere、それぞれ 1 つの条件を処理する 2 つの句:

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

LINQ クエリの実行は結果の呼び出しまで延期されるため、同等です。

于 2013-06-20T09:28:09.037 に答える
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 呼び出しがあり、2 番目の呼び出しが最初の結果を入力として受け取ることを示しています。
そのLinq to Objectsため、パフォーマンス ヒットが発生します。
パフォーマンスの低下の程度は、データの量と where 句の順序によって異なります。最初の句がフィルタリングされるほど、次の句が処理する必要が少なくなります...私の意見では、ほとんどの場合、パフォーマンスへの影響は大きくありません。

同じ SQL が作成されるため、Linq to SQL連鎖 Where 句はパフォーマンスに影響しません。

于 2013-06-25T10:06:41.843 に答える