2010-08-22 23 views
25

Merhaba Uygulamamdaki varlığa linq kullanıyorum.Varlık için linq kullanarak farklı kayıtlar alın

(User) 
ID 
Name 
Country 
DateCreated 

Ben dayalı tüm bu öğeleri ancak tekil seçmek gerekir: Aşağıda da görebileceğiniz gibi ben benzer bir tablo var Yani

bir sütun değeri "Ad" dayalı farklı kayıtları almak gerekir İsim (benzersiz). Eğer linq kullanarak gerçekleştirmek mümkün mü, eğer öyleyse lütfen bana nasıl olduğunu göster. o veritabanına DISTINCT SQL yüklemi göndermez çünkü

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

Her 'Ad' için birden çok kayıt olduğunu ima ettiniz. Eğer bu doğruysa, o zaman soru diğer alanların nasıl seçileceğini de belirtmelidir (id, ülke, daha önceden işlenmiş). Örneğin, her bir İsim için, rekoru minimum düzeyde işleme tabi tutmayı ister misiniz? – crokusek

cevap

27

Distinct() yöntem de gerçekleştirmez. Bunun yerine group kullanın:

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

LINQ grubu aslında mülkiyet anahtarlı varlıkların alt grupları oluşturur sen gösterir:

Smith 
    John 
    Mary 
    Ed 
Jones 
    Jerry 
    Bob 
    Sally 

sözdizimi yukarıdaki ayrı listede sonuçlanan anahtarlarını döndürür. Burada daha fazla bilgi:

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

+0

İç birleştirmeyi başka bir masaya kullanmam gerektiğini unutmuşum. Bana kod nasıl değiştirileceğini gösterebilir misin? – Boommer

+3

Distinct() aslında SQL'in DISTINCT yüklemini içermesine neden olur. Neden düşünmediğini düşünüyorsun?Tabii ki, ancak hala IQUeryables ile çalışıyorsanız bunu yapacağız .. ama öyle. –

+0

Bu cevap tamamen beni kurtardı: D Teşekkürler, Dave! – programad

8

anahtar ile ayrı grup seçmek adıyla gruba olduğunu ortaya tamamen LINQ yolu, o bağlı olarak seçin.

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

Düzenleme: Varlık Framework elbette çok popüler bir linq sağlayıcı olmakla (bu durumda) mantıksal olarak eşdeğer FirstOrDefault() iyi çalışır olsa, burada da First() işlemez. EF'in sınırlamaları nedeniyle'a zorlanmadığı zaman, First()'u tercih ediyorum, çünkü buradaki anlamı, burada aranan şeyle daha iyi eşleşiyor. Bu sadece farklı farklı tanımlar

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(); 

:

bir başka yolu, bir sınıf yardımcı tanımlamaktır. Performans, sorgu sağlayıcının eşitlik tanımını yorumlayıp yorumlayamayacağı ile farklılık gösterecektir. Kolaylık, benzer LINQ sorgularının aynı şeyi yapıp yapmadığına bağlı olarak farklılık gösterecektir.

+0

Birleştirme kullanarak birden çok tabloyu nasıl seçebilirim? – Boommer

+0

' iSrc’den jSrc’den jsrc’ye i.someField ile j.someField equ eşittir. Bu aynı soru değil, aynı soruyu eklemek ve eklemek yerine ayrı sorular sormak daha iyi olabilir. İnsanlar soruyu temel alan sorulara bakarlar ve birinin cevabını bilmek her zaman bir diğerine cevabı bilmeyi gerektirmez. –

+0

U beni yanlış anladı. Ben nasıl grup sormak ya da sadece ben aynı soruyu soruyorum ama iç birleştirme (birden fazla tablo) kullanarak nasıl. – Boommer

1

Merhaba, iç birleştirmeyle farklı kayıtları nasıl seçebiliyorsunuz.

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

Böyle bir şey kullanabilirsiniz yardımcı olur. Bir GridView denetimini benzersiz değerlerle doldurmanın bir örneğini gösterir. Teşekkürler!

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

İşte Svetlana yanıtı kapalı dayandığı kullanarak sona erdi başka varyasyonu: bu

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()); 
+0

Bu doğru cevap, çünkü OP linq sözdizimi hakkında sordu, lambda değil. –