web-dev-qa-db-ja.com

linq to entityを使用して個別のレコードを取得する

こんにちは、アプリケーションでlinq to entityを使用しています。 1つの列値「名前」に基づいて個別のレコードを取得する必要があります

だから私はあなたが以下に見ることができるような同様のテーブルを持っています:

(User)
ID
Name
Country
DateCreated

このアイテムすべてを選択する必要がありますが、名前に基づいて一意です(一意)。 linqを使用して達成することは可能ですか?その場合、方法を教えてください。

var items = (from i in user select new  {i.id, i.name, i.country, i.datecreated}).Distinct();
25
Boommer

Distinct()メソッドは、DISTINCT SQL述語をデータベースに送信しないため、適切に実行されません。代わりにgroupを使用してください:

var distinctResult = from c in result
             group c by c.Id into uniqueIds
             select uniqueIds.FirstOrDefault();

LINQのグループは、実際には、指定したプロパティをキーとするエンティティのサブグループを作成します。

Smith
  John
  Mary
  Ed
Jones
  Jerry
  Bob
  Sally

上記の構文は、キーを返し、個別のリストになります。詳細はこちら:

http://imar.spaanjaars.com/546/using-grouping-instead-of-distinct-in-entity-framework-to-optimize-performance

26
Dave Swersky

発生する純粋なLINQの方法は、名前でグループ化し、キーで個別のグループを選択し、それに基づいて選択することです。

_from i in user
group new {i.ID, i.Country, i.DateRecord} by i.Name into byNmGp
select byNmGp.First();
_

編集:Entity Frameworkはもちろん非常に人気のあるlinqプロバイダーですが、ここではFirst()をうまく処理しませんが、論理的に同等の(この場合)FirstOrDefault()は正常に機能します。 EFの制限によってFirst()に強制されない場合は、FirstOrDefault()を選択します。これは、その意味がここで求められているものとより一致するためです。

別の方法はヘルパークラスを定義することです:

_private class MyRecord : IEquatable<MyRecord>
{
  public int ID;
  public string Name;
  public string Country;
  public DateTime DateCreated;
  public bool Equals(MyRecord other)
  {
    return Name.Equals(other.Name);
  }
  public override bool Equals(object obj)
  {
    return obj is MyRecord && Equals((MyRecord)obj);
  }
  public override int GetHashCode()
  {
    return Name.GetHashCode();
  }
}
/*...*/
var items = (from i in user select new MyRecord {i.ID, i.Name, i.Country, i.DateRecord}).Distinct();
_

これは単に明確に異なって定義します。パフォーマンスは、クエリプロバイダーがその等価性の定義を解釈できるかどうかによって異なります。同じようなLINQクエリがほとんど同じことを行っているかどうかによって、利便性は異なります。

8
Jon Hanna

次のようなものを使用できます。

var distinctReports = reports.Select(c => c.CompanyCode)
                             .Distinct()
                             .Select(c => reports.FirstOrDefault(r => r.CompanyCode == c))
                             .ToList();
2

これが私が最終的に使用したもう1つのバリエーションで、スヴェトラーナからの応答に基づいています。 GridViewコントロールに一意の値を設定する例を示します。ありがとう!

        dataGridView_AnalyzeTestSuites.DataSource = (
            from tr in _db.TestResults
            where tr.TaskId == taskId
            select new { TestSuiteName = tr.Test.TestSuite.Name }
            ).Distinct().ToList();
1
GrayDwarf

こんにちは、ここでは、内部結合を使用して異なるレコードを選択する方法を示します。それが役に立てば幸い

var distinctrecords = 
(entity.Table.Join(entity.Table2, x => x.Column, y => y.Column, (x, y) => new {x, y})
             .Select(@t => new {@t.x.Column2, @t.y.Column3}))
             .GroupBy(t => t.Column2)
             .Select(g => g.FirstOrDefault());
1
Eugene