2009-05-26 28 views
33

Tôi đang cố gắng đưa vào danh sách thả xuống với các công ty dược phẩm, như Bayer, Medley, v.v ... Tôi nhận được tên từ DB và đề tài tên được lặp lại trong DB, nhưng với id khác nhau.Linq Distinct() theo tên để điền một danh sách thả xuống với tên và giá trị

Tôi đang cố gắng sử dụng LINQ Distinct(), nhưng tôi không muốn sử dụng trình so sánh bình đẳng. Có cách nào khác không?

Danh sách thả xuống của tôi phải được điền bằng id và tên của công ty.

Tôi đang cố gắng một cái gì đó như: công ty

var x = _partnerService 
      .SelectPartners() 
      .Select(c => new {codPartner = c.codPartner, name = c.name}) 
      .Distinct(); 

này đang hiển thị lặp lại trong DDL.

cảm ơn!

+0

Nếu công ty xuất hiện nhiều lần với các id khác nhau và bạn muốn chúng xuất hiện chỉ một lần, id nào sẽ được hiển thị? Cái đầu tiên? Không sao? –

+0

Id là nhận dạng – AndreMiranda

Trả lời

76

Các biểu thức sau đây sẽ chỉ lựa chọn các công ty khác nhau và trả lại xuất hiện đầu tiên với id của nó.

partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First()); 
+0

Xin chào Daniel! Đó là chính xác những gì tôi cần! Cảm ơn! :-) – AndreMiranda

+0

Chỉ cần hoàn hảo! :) – rafek

+0

khi tôi làm: dgvRecords.DataSource = (từ g trong dbContext.records chọn g) .GroupBy (g => g.ID) .Select (g => g.FirstOrDefault()); Tôi nhận được: Thông báo = Phương thức đã chỉ định không được hỗ trợ. Source = MySql.Data.Entity –

3

Các tác phẩm khác nhau trên toàn bộ lựa chọn. Nếu bạn bao gồm c.codPartner trong lựa chọn, và có hai giá trị khác nhau của c.codPartner cho cùng một c.name, thì bạn sẽ thấy hai hàng có cùng một tên.

0

chỉ cần vượt qua so sánh của riêng bạn với phương pháp Riêng biệt bằng cách sử dụng một trong các tình trạng quá tải khác.

(extension) IQueryable<T> IQueryable<T>.Distinct(IEqualityComparer<T> comparer) 
+0

Nó sẽ không thay đổi bất cứ điều gì ... nếu có một số công ty có cùng tên nhưng id khác nhau, làm thế nào bạn sẽ chọn id để sử dụng? –

+0

tôi đồng ý - việc chọn ID sẽ là một vấn đề. Nếu bạn muốn một ID cụ thể cho mỗi, sử dụng một khác biệt với một EqualityComparer có lẽ sẽ không phải là con đường để đi. Ngoài ra, hãy ghi nhớ về downvote ở đây rằng câu hỏi ban đầu không nói gì về việc chọn một ID cụ thể cho mỗi mục trong các kết quả riêng biệt ... –

1

Nếu bạn không chỉ định tham số IEqualityComparer, thì nó sẽ chỉ sử dụng Object.ReferenceEquals, xem giá trị GetHashKey đối tượng. Đối với các loại ẩn danh, chúng là duy nhất.

Bây giờ giải quyết điều này là một chút khó khăn, vì bạn không thể viết một IEqualityComparer cho một loại vô danh. Vì vậy, bạn muct tạo ra một loại thực sự cho vấn đề:

class Partner 
{ 
    public int codPartner {get; set;} 
    public string name {get; set;} 
    public override int GetHashCode() { return name .GetHashCode();} 
} 

var x = _partnerService.SelectPartners() 
     .Select(c => new Partner {codPartner = c.codPartner, name = c.name}) 
     .Distinct(); 
+0

ReferenceEquals không so sánh hashcodes, nó so sánh tham chiếu ... nó sẽ trả về true nếu hai tham chiếu trỏ đến cùng một ví dụ –

2

Tôi không nghĩ rằng bạn có thể làm điều này với một lớp vô danh, nhưng nếu bạn đã tạo một đối tượng dữ liệu như

class Foo 
{ 
    private int _ID; 

    public int ID 
    { 
     get { return _ID; } 
     set { _ID = value; } 
    } 
    private string _Name; 

    public string Name 
    { 
     get { return _Name; } 
     set { _Name = value; } 
    } 

} 

bạn có thể tạo một đối tượng comparer như

class FooComparer : IEqualityComparer<Foo> 
{ 


    public bool Equals(Foo x, Foo y) 
    { 
     return x.Name == y.Name; 
    } 

    public int GetHashCode(Foo obj) 
    { 
     return obj.GetHashCode(); 
    } 

} 
17
var distinctCompanies = Companies 
    .GroupBy(c => c.CompanyName) 
    .Select(g => g.First()); 
+0

xin lỗi để hỏi, nhưng từ 'g' từ đâu? Các công ty – StarCub

+1

@StarCub là một số điện thoại có thể truy cập được . GroupBy chấp nhận điều đó và trả về chuỗi > của IEnumerable. Mỗi mục trong Chọn là một IGrouping . Tôi đã sử dụng một tên khác để tạo sự khác biệt trong loại rõ ràng hơn. –

1

Distinc sẽ sử dụng GetHashCode nếu bạn không nói với nó (thông qua một IEqualityComparer) để sử dụng phương pháp khác. Bạn có thể sử dụng một EqualityComparer chung chung, như thế này:

public class GenericEqualityComparer<T> : IEqualityComparer<T> 
{  
    private Func<T, T, Boolean> comparer;  

    public GenericEqualityComparer(Func<T, T, Boolean> comparer)  
    {   
     this.comparer = comparer;  
    }  

    #region IEqualityComparer<T> Implementation 

    public bool Equals(T x, T y)  
    {   
     return comparer(x, y);  
    }  

    public int GetHashCode(T obj)  
    { 
     return obj.GetHashCode(); 
    }  

    #endregion 
} 

và sau đó sử dụng như thế này (kindof)

public static IEqualityComparer<YourType> MyComparer 
{ 
    get 
    { 
     return new GenericEqualityComparer<YourType>((x, y) => 
     { 
      return x.name.Equals(y.name); 
     }); 
     } 
} 
Các vấn đề liên quan