2012-02-07 40 views
39

Tôi có truy vấn kết hợp tham gia và nhóm, nhưng tôi gặp sự cố. Truy vấn giống như:LINQ: kết hợp tham gia và nhóm theo

var result = from p in Products       
join bp in BaseProducts on p.BaseProductId equals bp.Id      
group p by p.SomeId into pg       
select new ProductPriceMinMax { 
     SomeId = pg.FirstOrDefault().SomeId, 
     CountryCode = pg.FirstOrDefault().CountryCode, 
     MinPrice = pg.Min(m => m.Price), 
     MaxPrice = pg.Max(m => m.Price), 
     BaseProductName = bp.Name <------ can't use bp. 
}; 

Như bạn thấy, nó tham gia bảng Sản phẩm với bảng BaseProducts và nhóm trên id của bảng Sản phẩm. Nhưng trong kết quả ProductPriceMinMax, tôi cũng cần một thuộc tính của bảng BaseProducts: bp.Name, nhưng nó không biết bp.

Bất kỳ ý tưởng nào tôi đang làm sai?

Cảm ơn!

Trả lời

64

Một khi bạn đã làm điều này

group p by p.SomeId into pg 

bạn không còn có thể truy cập các biến phạm vi sử dụng trong đầu from. Tức là, bạn không còn có thể nói về p hoặc bp, bạn chỉ có thể nói về pg.

Hiện tại, pgnhóm và do đó chứa nhiều hơn một sản phẩm. Tất cả các sản phẩm trong một nhóm pg nhất định có cùng một SomeId (vì đó là những gì bạn nhóm theo), nhưng tôi không biết liệu điều đó có nghĩa là tất cả chúng đều có cùng một BaseProductId hay không.

Để có được một tên sản phẩm cơ bản, bạn phải chọn một sản phẩm cụ thể trong nhóm pg (Như bạn đang làm với SomeIdCountryCode), và sau đó tham gia để BaseProducts.

var result = from p in Products       
group p by p.SomeId into pg       
// join *after* group 
join bp in BaseProducts on pg.FirstOrDefault().BaseProductId equals bp.Id   
select new ProductPriceMinMax { 
     SomeId = pg.FirstOrDefault().SomeId, 
     CountryCode = pg.FirstOrDefault().CountryCode, 
     MinPrice = pg.Min(m => m.Price), 
     MaxPrice = pg.Max(m => m.Price), 
     BaseProductName = bp.Name // now there is a 'bp' in scope 
}; 

Điều đó có vẻ khá lạ và tôi nghĩ bạn nên quay lại và xem xét những gì bạn đang thực sự cố truy xuất.

+1

Điều này tốt hơn giải pháp của chúng tôi :) Cảm ơn. –

+1

xem http://stackoverflow.com/a/2877012/1923685 –

+0

@AakashM Cảm ơn. Nhưng tôi đang lấy một vấn đề với groupVariable.FirstOrDefault(). Column_name. Khi tôi sẽ truy cập vào biến IQueryable Kết quả sau đó lỗi xảy ra mà tiêu đề là ** "entitycommandexecutionexception đã được unhandled bởi mã người dùng" ** với body *** "Đã xảy ra lỗi khi thực thi định nghĩa lệnh. "*** Tôi không thể hiểu chuyện gì đang xảy ra. –

17

Chúng tôi đã làm điều đó như thế này:

from p in Products       
join bp in BaseProducts on p.BaseProductId equals bp.Id      
where !string.IsNullOrEmpty(p.SomeId) && p.LastPublished >= lastDate       
group new { p, bp } by new { p.SomeId } into pg  
let firstproductgroup = pg.FirstOrDefault() 
let product = firstproductgroup.p 
let baseproduct = firstproductgroup.bp 
let minprice = pg.Min(m => m.p.Price) 
let maxprice = pg.Max(m => m.p.Price) 
select new ProductPriceMinMax 
{ 
SomeId = product.SomeId, 
BaseProductName = baseproduct.Name, 
CountryCode = product.CountryCode, 
MinPrice = minprice, 
MaxPrice = maxprice 
}; 

EDIT: chúng tôi sử dụng các phiên bản của AakashM, bởi vì nó có hiệu suất tốt hơn

4

tôi gặp vấn đề tương tự như bạn.

Tôi đẩy hai tablesresult vào t1 đối tượng và nhóm t1.

from p in Products       
    join bp in BaseProducts on p.BaseProductId equals bp.Id 
    select new { 
    p, 
    bp 
    } into t1 
group t1 by t1.p.SomeId into g 
select new ProductPriceMinMax { 
    SomeId = g.FirstOrDefault().p.SomeId, 
    CountryCode = g.FirstOrDefault().p.CountryCode, 
    MinPrice = g.Min(m => m.bp.Price), 
    MaxPrice = g.Max(m => m.bp.Price), 
    BaseProductName = g.FirstOrDefault().bp.Name 
}; 
Các vấn đề liên quan