2010-09-28 37 views
7

Với truy vấn này:Vấn đề với LINQ to Entities truy vấn sử dụng Sum trên đối tượng con sở hữu

from s in services 
select new 
{ 
    s.Id, 
    s.DateTime, 
    Class = s.Class.Name, 
    s.Location, 
    s.Price, 
    HeadCount = s.Reservations.Sum(r => r.PartySize), // problem here. r.PartySize is int 
    s.MaxSeats 
} 

Nếu dịch vụ không có bất kỳ đặt phòng, ngoại lệ này được ném:

System.InvalidOperationException : Giá trị đúc thành giá trị 'Int32' không thành công do giá trị vật hoá là null. Tham số chung của loại kết quả hoặc truy vấn phải sử dụng một loại nullable.

Tôi hiểu, nhưng làm cách nào để giải quyết? Ý định của tôi là nếu không có đặt phòng, sau đó số lượng nhân viên được chỉ định 0.

Trả lời

7

Bạn nên kiểm tra cho nó:

HeadCount = s.Reservations != null ? s.Reservations.Sum(r => r.PartySize) : 0, 
+0

tôi đăng câu hỏi này trước khi thử mà chỉ vì tôi cho rằng LINQ to entites sẽ không thể chuyển nó sang SQL hoặc một cái gì đó như thế. Tôi vẫn quen với L2E, có vẻ khó tính hơn LINQ to SQL là về những gì bạn thực sự có thể làm bên trong câu lệnh LINQ. Dù sao, công trình này và người ta không bao giờ nên giả định. Cảm ơn. –

+0

@Ronnie vui vì nó hoạt động. Họ chắc chắn khác nhau và tôi tưởng tượng L2E sẽ chỉ trở nên linh hoạt hơn trong tương lai. –

+0

Thao tác này sẽ hoạt động nhưng có giải pháp dễ dàng hơn. –

1

Một nhà điều hành ternary đơn giản nên khắc phục vấn đề độc đáo ...

cái gì đó như này:

HeadCount = (s.Reservations != null && s.Reservations.Any()) ? s.Reservations.Sum(r => r.PartySize) : 0; 

này sẽ xử lý cho cả hai tình huống vô trống

+0

Tôi không nghĩ rằng mã đó thậm chí sẽ biên dịch (thiếu '()'). Nó chắc chắn sẽ không tạo ra SQL hiệu quả (không bao giờ sử dụng '.Count() == 0' khi bạn ngụ ý' Any() '), nhưng thậm chí cả hai đều không hiệu quả và khó đọc so với. L2E được xây dựng trong null coalesce). –

+0

Bạn nói đúng, nó sẽ không biên dịch vì Count thiếu '()'. Đã viết nó trên bay -_-. Bất kỳ cũng sẽ hiệu quả hơn. Cảm ơn vì sự đúng đắn của bạn! –

11

Có một giải pháp đơn giản hơn:

from s in services 
select new 
{ 
    s.Id, 
    s.DateTime, 
    Class = s.Class.Name, 
    s.Location, 
    s.Price, 
    HeadCount = (int?)s.Reservations.Sum(r => r.PartySize), 
    s.MaxSeats 
} 

Ghi chú phôi. Điều này cũng có thể tạo ra SQL đơn giản hơn đề xuất của @ Ahmad.

Về cơ bản, bạn chỉ đang giúp loại suy luận.

+0

Theo OP 'Đặt trước' có thể là' null' vì vậy cố gắng gọi 'Sum (...)' trên một null là không thể. Việc truyền tới một 'int?' Sẽ không bỏ qua ngoại lệ null sẽ xảy ra khi chạy. Có lẽ bạn đang nghĩ đến việc đúc một giá trị null trực tiếp, như '(int?) R.PartySize'? –

+2

@Ahmad, điều đó không đúng đối với L2E, mặc dù nó đúng cho L2O. Họ có các quy tắc khác nhau. Không, tôi không nghĩ đến việc đúc giá trị. Hãy thử mã tôi đề nghị; nó hoạt động. –

+1

+1 Tôi đã bỏ qua bản dịch diễn ra cho nhà cung cấp LINQ này. –

2

này nên giải quyết vấn đề của bạn: Cố gắng chi phí int để int?

from s in services 
select new 
{ 
    s.Id, 
    s.DateTime, 
    Class = s.Class.Name, 
    s.Location, 
    s.Price, 
    HeadCount = s.Reservations.Sum(r => (int?) r.PartySize), 
    s.MaxSeats 
}; 
HeadCount = HeadCount ?? 0; 
Các vấn đề liên quan