複数 - where in c# linq




LINQを使って "not in"クエリを実行する方法は? (10)

2番目のリストに電子メールが存在しない最初のリストの項目。

from item1 in List1
where !(list2.Any(item2 => item2.Email == item1.Email))
select item1;

私は両方のコレクションにプロパティEmailを持つ2つのコレクションを持っています。 私はEmailが2番目のリストに存在しない最初のリストの項目のリストを取得する必要があります。 SQLでは "not in"を使用するだけですが、LINQの同等機能はわかりません。 それはどうですか?

これまでのところ私は参加しています...

var matches = from item1 in list1
join item2 in list2 on item1.Email equals item2.Email
select new { Email = list1.Email };

しかし、私は違いが必要なので私は参加することができず、参加は失敗します。 私はContainsやExistsを使う方法が必要です。 私はまだそれを行う例を見つけていません。


C#でSQLに似たIN演算子を使用したい人は、次のパッケージをダウンロードしてください:

Mshwf.NiceLinq

それはInメソッドとNotInメソッドをNotInます:

var result = list1.In(x => x.Email, list2.Select(z => z.Email));

この方法でも使用できます

var result = list1.In(x => x.Email, "[email protected]", "[email protected]", "[email protected]");

ADO.NET Entity Frameworkを使用している場合、EchoStormのソリューションも完全に機能します。 しかし、私の頭を包み込むのに数分かかった。 あなたがデータベースコンテキストdcを持っていてテーブルyにリンクされていないテーブルxの行を探したいとすると、完全な答えの答えは次のようになります:

var linked =
  from x in dc.X
  from y in dc.Y
  where x.MyProperty == y.MyProperty
  select x;
var notLinked =
  dc.X.Except(linked);

Andyのコメントに答えて、はい、LINQクエリで2つのfromを持つことができます。 ここでは、リストを使用した完全な使用例を示します。 各クラスのFooとBarにはIdがあります。 FooはFoo.BarId経由でBarへの「外部キー」参照を持っています。 プログラムは、対応する棒にリンクされていないすべてのFooを選択します。

class Program
{
    static void Main(string[] args)
    {
        // Creates some foos
        List<Foo> fooList = new List<Foo>();
        fooList.Add(new Foo { Id = 1, BarId = 11 });
        fooList.Add(new Foo { Id = 2, BarId = 12 });
        fooList.Add(new Foo { Id = 3, BarId = 13 });
        fooList.Add(new Foo { Id = 4, BarId = 14 });
        fooList.Add(new Foo { Id = 5, BarId = -1 });
        fooList.Add(new Foo { Id = 6, BarId = -1 });
        fooList.Add(new Foo { Id = 7, BarId = -1 });

        // Create some bars
        List<Bar> barList = new List<Bar>();
        barList.Add(new Bar { Id = 11 });
        barList.Add(new Bar { Id = 12 });
        barList.Add(new Bar { Id = 13 });
        barList.Add(new Bar { Id = 14 });
        barList.Add(new Bar { Id = 15 });
        barList.Add(new Bar { Id = 16 });
        barList.Add(new Bar { Id = 17 });

        var linked = from foo in fooList
                     from bar in barList
                     where foo.BarId == bar.Id
                     select foo;
        var notLinked = fooList.Except(linked);
        foreach (Foo item in notLinked)
        {
            Console.WriteLine(
                String.Format(
                "Foo.Id: {0} | Bar.Id: {1}",
                item.Id, item.BarId));
        }
        Console.WriteLine("Any key to continue...");
        Console.ReadKey();
    }
}

class Foo
{
    public int Id { get; set; }
    public int BarId { get; set; }
}

class Bar
{
    public int Id { get; set; }
}

All()使用することもできます

var notInList = list1.Where(p => list2.All(p2 => p2.Email != p.Email));

あなたはどこにもいなくても見つけることができる組み合わせを使うことができます:

var NotInRecord =list1.Where(p => !list2.Any(p2 => p2.Email  == p.Email));

ありがとう、ブレット。 あなたの提案も私を助けました。 私はオブジェクトのリストを持っていて、オブジェクトの別のリストを使ってそれをフィルタリングしたいと思っていました。 再度、感謝します....

誰かが必要な場合は、私のコードサンプルを見てください:

'First, get all the items present in the local branch database
Dim _AllItems As List(Of LocalItem) = getAllItemsAtBranch(BranchId, RecordState.All)

'Then get the Item Mappings Present for the branch
Dim _adpt As New gItem_BranchesTableAdapter
Dim dt As New ds_CA_HO.gItem_BranchesDataTable
    _adpt.FillBranchMappings(dt, BranchId)

Dim _MappedItems As List(Of LocalItem) = (From _item As LocalItem In _AllItems Join _
    dr As ds_CA_HO.gItem_BranchesRow In dt _
    On _item.Id Equals dr.numItemID _
    Select _item).ToList

_AllItems = _AllItems.Except(_MappedItems.AsEnumerable).ToList

 Return _AllItems

グループが空の場合、最初のリストから項目を選択するだけで、外部結合はできませんでしたか? 何かのようなもの:

Dim result = (From a In list1
              Group Join b In list2 
                  On a.Value Equals b.Value 
                  Into grp = Group
              Where Not grp.Any
              Select a)

私はこれがEntityフレームワークと効率的な方法で動作するかどうかは不明です。


メモリ内のオブジェクトのグループから始め、データベースに対してクエリを実行している人にとっては、これが最善の方法であることがわかりました。

var itemIds = inMemoryList.Select(x => x.Id).ToArray();
var otherObjects = context.ItemList.Where(x => !itemIds.Contains(x.Id));

これは、SQLのnice WHERE ... IN (...)節を生成します。


単純化のためにintのリストを使用する例。

List<int> list1 = new List<int>();
// fill data
List<int> list2 = new List<int>();
// fill data

var results = from i in list1
              where !list2.Contains(i)
              select i;

foreach (var result in results)
    Console.WriteLine(result.ToString());

私はLINQ to Entitiesこれをテストしなかった:

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers 
    where !dc.Orders.Any(o => o.CustomerID == c.CustomerID)   
    select c;

あるいは:

NorthwindDataContext dc = new NorthwindDataContext();    
dc.Log = Console.Out;

var query =    
    from c in dc.Customers 
    where dc.Orders.All(o => o.CustomerID != c.CustomerID)   
    select c;

foreach (var c in query) 
    Console.WriteLine( c );




linq