2011-08-29 26 views
5

Tôi có một bảng, cho phép gọi nó là Ghi. Có chứa: ID (int) | CustID (int) | Thời gian (datetime) | Dữ liệu (varchar)C# LINQ truy vấn (MYSQL EF) - Bản ghi riêng biệt và mới nhất

tôi cần những kỷ lục mới nhất (gần đây nhất) cho mỗi khách hàng:

SQL phiên bản

select * from record as i group by i.custid having max(id); 

LINQ 1

dgvLatestDistinctRec.DataSource = from g in ee.Records 
            group g by g.CustID into grp 
            select grp.LastOrDefault(); 

này ném một lỗi:

System.NotSupportedException was unhandled by user code Message=LINQ to Entities does not recognize the method 'Faizan_Kazi_Utils.Record LastOrDefault[Record ](System.Collections.Generic.IEnumerable`1[Faizan_Kazi_Utils.Record ])' method, and this method cannot be translated into a store expression. Source=System.Data.Entity

LINQ phiên bản 2

var list = (from g in ee.Records 
      group g by g.CustID into grp 
      select grp).ToList(); 
Record[] list2 = (from grp in list 
        select grp.LastOrDefault()).ToArray(); 
dgvLatestDistinctRec.DataSource = list2; 

này hoạt động, nhưng không hiệu quả vì nó tải TẤT CẢ các bản ghi từ cơ sở dữ liệu vào bộ nhớ và sau đó trích xuất chỉ (thành viên gần đây nhất) cuối cùng của mỗi nhóm.

Có giải pháp LINQ nào tiếp cận hiệu quả và khả năng đọc của giải pháp SQL đã đề cập không?

+0

Cách bạn đã đạt được Mysql + LINQ. DBSet có hỗ trợ Mysql không. Nếu vậy, bạn có thể vui lòng nói như thế nào ?. Tôi đã chết để đạt được điều này, và đã bỏ cuộc vào tuần trước. – prabhakaran

+0

Tôi chỉ cần các điểm cốt lõi, ít nhất là nơi bạn đặt chuỗi kết nối đó. – prabhakaran

Trả lời

4

Cập nhật:

var results = (from rec in Record group rec by rec.CustID into grp 
    select new 
    { 
     CustID = grp.Key, 
     ID = grp.OrderByDescending(r => r.ID).Select(x => x.ID).FirstOrDefault(), 
     Data = grp.OrderByDescending(r => r.ID).Select(x => x.Data).FirstOrDefault() 
    } 
); 

Vì vậy, tôi đã làm một bảng kiểm tra và đã viết một LINQ -> Query SQL mà sẽ thực hiện chính xác những gì bạn cần. Hãy xem cái này và cho tôi biết bạn nghĩ gì. Chỉ có điều cần ghi nhớ nếu truy vấn này được thu nhỏ tôi tin rằng nó sẽ chạy một truy vấn đến DB cho mỗi và mọi bản ghi CustID sau khi nhóm trong lựa chọn mới. Cách duy nhất để chắc chắn sẽ để chạy SQL Tracer khi bạn chạy các truy vấn để biết về điều đó đi đây .. http://www.foliotek.com/devblog/tuning-sql-server-for-programmers/

gốc:

Bạn có thể làm một cái gì đó như thế này? from g in ee.Records where g.CustID == (from x in ee.Records where (g.CustID == x.CustID) && (g.ID == x.Max(ID)).Select(r => r.CustID))

Đó là tất cả mã giả nhưng hy vọng bạn sẽ có được ý tưởng.

+0

Ok, vì vậy tôi đã thử những gì bạn đang nói và các lỗi của nó về hai điểm: Delegate System.Func 'không dùng 1 đối số –

+0

và trên ID trong Max (ID) của nó cho: Tên 'id' không tồn tại trong bối cảnh hiện tại –

+0

Tôi nhận được những gì bạn đang cố gắng làm, nhưng tôi đã không thể thực hiện các thay đổi cần thiết để làm cho nó hoạt động: s –

1

Tôi nghĩ grp.LastOrDefault(), một hàm C#, là thứ mà SQL không biết. LINQ biến truy vấn của bạn thành truy vấn SQL cho máy chủ db của bạn để hiểu. Bạn có thể muốn thử và tạo một thủ tục được lưu trữ thay thế, hoặc một cách khác để lọc ra những gì bạn đang tìm kiếm.

Lý do truy vấn thứ hai của bạn hoạt động là vì LINQ to SQL trả về danh sách và sau đó bạn thực hiện truy vấn LINQ (để lọc ra những gì bạn cần) trên danh sách C#, thực hiện giao diện IEnumerable/IQueryable và hiểu grp .LastOrDefault().

+0

True, LastOrDefault không được triển khai trong nhà cung cấp MySQL Entity Framework (như lỗi hiển thị). –

+0

Yup, nó trả về một danh sách dài như một bộ sưu tập trong bộ nhớ, sau đó được lọc xuống các mục duy nhất trên mỗi CustID, điều này không lý tưởng về việc sử dụng bộ nhớ và bộ xử lý. Và đó là lý do tại sao tôi đang tìm kiếm sự giúp đỡ ở đây :) –

1

Điều gì xảy ra nếu bạn thay thế LastOrDefault() bằng Simple Last() đơn giản? (Có, bạn sẽ phải kiểm tra bảng hồ sơ của bạn không có sản phẩm nào)

Bởi vì tôi không thể thấy cách MySQL có thể trả về nhóm "Mặc định". Đây không phải là thứ có thể được dịch sang SQL đơn giản.

+0

Khi tôi sử dụng lần cuối tôi nhận được lỗi này: System.NotSupportedException được unhandled bởi mã người dùng Message = LINQ to Entities không nhận ra phương thức 'Faizan_Kazi_Utils.Record Last [Record] (Hệ thống .Collections.Generic.IEnumerable'1 [Faizan_Kazi_Utils.Record]) 'phương pháp, và phương pháp này không thể được dịch sang một biểu thức cửa hàng. Nguồn = System.Data.Entity –

0

Tôi có một ý tưởng:

// Get a list of all the id's i need by: 
// grouping by CustID, and then selecting Max ID from each group. 
var distinctLatest = (from x in ee.Records 
          group x by x.CustID into grp 
          select grp.Max(g => g.id)).ToArray(); 

// List<Record> result = new List<Record>(); 

//now we can retrieve individual records using the ID's retrieved above 
// foreach (int i in distinctLatest) 
// { 
// var res = from g in ee.Records where g.id == i select g; 
// var arr = res.ToArray(); 
// result.Add(res.First()); 
// } 

// alternate version of foreach 
dgvLatestDistinctRec.DataSource = from g in ee.Records 
              join i in distinctLatest 
              on g.id equals i 
              select g; 
+0

đây là kinda dựa trên giải pháp bigamils ​​... nó tạo ra dòng suy nghĩ này trong đầu của tôi –

+0

Bạn thực sự không muốn làm. ToArray() hoặc ToList() vào thời điểm này bởi vì điều đó sẽ trả về tất cả các bản ghi và đặt chúng vào ký ức. Bạn muốn LINQ -> SQL làm tất cả công việc. Về cơ bản nó xây dựng một cây biểu thức động và không thực sự thực thi bất kỳ SQL nào cho đến khi bạn yêu cầu một giá trị. Những điều quan trọng mà yêu cầu một vall (ToList(), ToArray(), First(), Last() vv) xin lỗi nếu tôi đang thừa. Anyways cập nhật câu trả lời của tôi để làm chính xác những gì bạn cần. Xin vui lòng upvote/đánh dấu tôi như là câu trả lời nếu nó làm việc cho bạn! Hy vọng điều này là hữu ích – bigamil

+0

hmmm ... nhưng đầu tiên. ToArray chỉ tải một vài số nguyên vào bộ nhớ (id riêng biệt của cust) và sau đó là thứ hai thực hiện chính xác những gì tôi cần (tải toàn bộ hồ sơ: hồ sơ mới nhất cho từng khách hàng riêng biệt) ... không phải thế sao? –

2

Tôi có thể là quá muộn để giúp đỡ với vấn đề của bạn, nhưng tôi có một vấn đề tương tự và đã có thể để có được những kết quả mong muốn với một truy vấn như thế này:

from g in ee.Records 
group g by g.CustID into grp 
from last in (from custRec in grp where custRec.Id == grp.Max(cr => cr.Id) select custRec) 
select last 
+0

điều này thật tuyệt vời. .. hiệu suất tốt! –

Các vấn đề liên quan