2010-08-22 6 views
25

Xin chào Tôi đang sử dụng LINQ cho thực thể trong đơn đăng ký của mình. Tôi cần phải nhận được hồ sơ riêng biệt dựa trên một giá trị cột "Tên"Nhận hồ sơ riêng biệt bằng cách sử dụng LINQ to entity

Vì vậy, tôi có một bảng tương tự như bạn có thể xem dưới đây:

(User) 
ID 
Name 
Country 
DateCreated 

tôi cần phải chọn tất cả các mục này nhưng uniques dựa trên Tên (duy nhất). Có thể thực hiện bằng cách sử dụng LINQ, nếu vậy xin vui lòng chỉ cho tôi cách.

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

Bạn đã ngụ ý có nhiều bản ghi cho mỗi 'Tên'. Nếu điều đó là đúng, thì câu hỏi cũng nên chỉ ra cách chọn các trường khác (id, quốc gia, datecreated). Ví dụ, đối với mỗi Tên, bạn có muốn bản ghi với mức tối thiểu được thiết lập không? – crokusek

Trả lời

27

Phương thức Distinct() không hoạt động tốt vì nó không gửi vị từ SQL DISTINCT đến cơ sở dữ liệu. Sử dụng group thay vì: nhóm

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

LINQ của thực sự tạo ra các phân nhóm các đơn vị keyed bởi tài sản bạn cho biết:

Smith 
    John 
    Mary 
    Ed 
Jones 
    Jerry 
    Bob 
    Sally 

Cú pháp trên trả về các phím, kết quả trong một danh sách riêng biệt. Biết thêm thông tin ở đây:

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

+0

Tôi quên tôi cần phải sử dụng tham gia bên trong để bàn khác. Bạn có thể chỉ cho tôi cách thay đổi mã không? – Boommer

+3

Sự khác biệt() thực tế làm cho SQL bao gồm biến vị ngữ DISTINCT. Tại sao bạn nghĩ rằng nó không?Tất nhiên nó sẽ chỉ làm như vậy nếu bạn vẫn đang làm việc với IQUeryables .. nhưng nó có. –

+0

Câu trả lời này hoàn toàn cứu tôi: D Cảm ơn, Dave! – programad

8

Các đơn thuần LINQ như vậy xảy ra là để nhóm theo tên, chọn nhóm riêng biệt theo mã, sau đó chọn dựa trên đó.

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

Edit: Entity Framework là tất nhiên một nhà cung cấp LINQ rất phổ biến, nhưng nó không xử lý First() tốt ở đây, mặc dù logic tương đương (trong trường hợp này) FirstOrDefault() sẽ hoạt động tốt. Tôi thích First() khi không bị ép buộc vào FirstOrDefault() bởi những hạn chế của EF, vì ý nghĩa của nó phù hợp hơn với những gì được tìm kiếm ở đây.

Một cách khác là xác định một lớp helper:

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

này chỉ đơn giản định nghĩa riêng biệt khác nhau. Hiệu suất sẽ khác nhau tùy theo nhà cung cấp truy vấn có thể giải thích định nghĩa bình đẳng đó hay không. Tiện lợi sẽ khác nhau dựa trên việc bạn có các truy vấn LINQ tương tự làm nhiều điều tương tự hay không.

+0

Tôi làm cách nào để có thể thực hiện nhiều bảng bằng cách sử dụng tính năng kết nối? – Boommer

+0

'i từ iSrc tham gia j từ jSrc trên i.someField bằng j.someField'. Nó không phải là cùng một câu hỏi như thế này mặc dù, nó có thể được tốt hơn để đặt câu hỏi riêng biệt hơn là thêm và thêm vào cùng một. Mọi người nhìn vào các câu hỏi dựa trên câu hỏi, và biết câu trả lời cho câu hỏi không phải luôn luôn đòi hỏi phải biết câu trả lời cho câu hỏi khác. –

+0

U hiểu lầm tôi. Tôi hỏi làm thế nào để nhóm hoặc chỉ làm thế nào để thực hiện cùng một mà tôi yêu cầu, nhưng bằng cách sử dụng bên trong tham gia (nhiều bảng). – Boommer

1

Xin chào ở đây là cách bạn có thể chọn các bản ghi riêng biệt với tham gia bên trong. Hy vọng nó giúp

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

Bạn có thể sử dụng một cái gì đó như thế này:

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

Dưới đây là một biến thể tôi đã kết thúc sử dụng được dựa trên phản hồi từ Svetlana. Hiển thị ví dụ về cách điều khiển GridView với các giá trị duy nhất. Cảm ơn!

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

Đây là câu trả lời đúng, vì OP hỏi về cú pháp LINQ, không phải lambda. –