2010-12-17 22 views
12

Bir IQueryable almak için LINQ kullanarak bir DataBase'den kayıtları çeken bir İşlev yazıyorum. Bu LINQ ifadesi, belirli bir süre içinde Active kullanıcıları için tüm kayıtları çeker ve ardından UserID, Ad ve Soyadını bir Telerik RadGrid'e tükürür.LINQ ile farklı bir IQueryable döndürmek?

Sorunum, bu Verileri çekerken UserID üzerinde Distinct Value almaya çalışırken yatmaktadır. Sonucu almak için bu kodu tekrar çalışmayı denedim. İşte, Tüm Değerleri ÇALIŞTIRMAK ile birlikte tüm Verileri çeken kodun bir örneği.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c).Distinct(); 

    return Employees; 
} 

benim Izgara DataSource uyguladıktan sonra, bu o Dönemi için her kullanıcı kayıt için 4 kez, bir örneğini döndürür.

alt text

bu esere ben bunu amaçladığınız şekilde yapmak benim LINQ Fonksiyonu için Farklı uygulamak için bir yolu var mı?

cevap

20

Bunu nesne ile yapmanın en kolay yolu, groupby'yi kullanıp ilkini seçmektir.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c).GroupBy(g=>g.DataSystem_Employees.AccID).Select(x=>x.FirstOrDefault()); 

    return Employees; 
} 

Bu, sınanmış değil, ancak genel kavram var.

Edit: Orijinali burada bir yerde bulmakta olduğunu hatırlıyorum. Nesneleri belirli bir özellik tarafından gruplandırmak için buna göz atın. LINQ's Distinct() on a particular property

+1

GroupBy mükemmel çalıştı!Sorun Giderme sırasında GroupBy'yi ilk başta denedim, ancak .Select'i (x => x.FirstOrDefault()) özledim. Teşekkürler! – Lando

+0

Sipariş, firstordefault'dan önce gruptan sonra seçimde olmalıdır. giriş zamanını önemsediğinizi varsayarak. –

4

Yalnızca görüntülemek istediğiniz alanlara döndüğünüz nesneleri sınırlarsanız, düzgün şekilde çalışır.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c.DataSystem_Employees.FName, 
          c.DataSystem_Employees.LName, 
          c.ID).Distinct(); 

    return Employees; 
} 
+0

Teoride bu işe yaramalıydı, ancak IntelliSense, Bildirime birden fazla Öğe eklemeye çalışırken beni reddetti. – Lando

+0

Ne tür bir hata alıyorsunuz? – sgriffinusa

+0

@sgriffinusa, "yeni {}" yi seçmeniz gerekiyor ... sözdizimi geçersiz –

4

deneyin ve nesne türü için bir IEqualityComparer<T> yazma seçilmiş ve Distinct yöntemle

+2

olduğu gibi bu, nesneler için linq kullanacak bir sorgu oluşturmuyor –

2

nesnelerde çeşitli alanlarda isimleri etrafında bazı varsayımlarda bulunmak kullanmak ediliyor:

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select new { FirstName = c.DataSystem_Employees.FName, LastName = c.DataSystem_Employees.LName, ID = c.DataSystem_Employees.ID }).Distinct(); 

    return Employees; 
} 

MVC modelini takip etmek için bu sorguyu Modelinize kaldırmak ve bu alanları içeren belirli bir sınıfı iade etmek isteyebilirsiniz.

-1

Sorun, her satırı farklı yapacak alanları geri çekiyor olmanızdır. Sgriffinusa'nın dediği gibi, sadece görüntülediğiniz 3 değeri geri çekin.

-1

Farklı yöntem için özel bir karşılaştırıcı uygulamak isteyebilirsiniz. Lütfen bir önceki SO sorusuna bakın here.

0

Bunu yapmak için Distinct() yöntemini kullanın. Örnek:

var query = from Notification in db.Notifications 

         select Notification.client ; 
      query=query.Distinct(); 

elde edilen sorgu yalnızca farklı değerlerini içerir.