2011-12-29 34 views
12

Nếu tôi làm:Tại sao tổng của một tập trống rỗng?

int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID).Sum(c => c.Plays); 

Nếu không có hồ sơ được trả về trong truy vấn này nó ném:

System.InvalidOperationException: Các giá trị null không thể được gán cho thành viên với kiểu System.Int32 mà là một loại giá trị không nullable.

Cách duy nhất để làm cho nó trở về 0 là bằng cách làm:

int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID).Sum(c => (int?)c.Plays) ?? 0; 

Trong cơ sở dữ liệu c.Plays là một int nullable.

Trong lý thuyết tập hợp, tổng của một tập hợp rỗng phải bằng 0 (ref). Làm thế nào đến trong Linq-to-SQL họ đã quyết định để làm cho nó trở về null?

+4

Đây là cơ sở dữ liệu và lý thuyết tập hợp ít hơn. 'SUM' của cột rỗng trong SQL Server là gì? – Marc

+0

@Marc trong câu hỏi tôi liên kết với không có cột nào được đề cập là không có giá trị –

+1

L2S dbml có biết rằng đối với tập dữ liệu này không? Tôi sẽ giả sử rằng trường sẽ là một 'int' và không phải là một' int? 'Nếu như vậy. – Marc

Trả lời

9

According to a source at Microsoft, Sum() trên một tập rỗng là null vì cách nó hoạt động trong SQL:

khi bảng được sản phẩm nào Tôi đang nhận được ngoại lệ này: InvalidOperationException

Trong Toán tử tổng hợp SQL, Sum() trả về null cho một tập rỗng. Vì vậy, đây là như thiết kế.

+16

"... như thiết kế sai. " – starblue

+1

Nhưng nếu bạn sử dụng Sum trên một IEnumerable rỗng, sau đó nó trả về đúng 0. Vì vậy, Microsoft đã chọn để làm cho Sum() trên IQueryable để phù hợp với SQL nhưng không phù hợp với Sum() trên IEnumerable. Lựa chọn mơ hồ ... – JustAMartin

0

Bạn có thể sử dụng phương pháp tổng quát hơn Aggregate với một hạt giống không:

int updateGamePlays = db.tblArcadeGames 
    .Where(c => c.ParentGameID == GameID) 
    .Aggregate(0, (a, c) => a + c.Plays); 

này không yêu cầu sử dụng các loại nullable.

+0

Tôi không biết về LINQ to SQL, nhưng LINQ to Entities không hỗ trợ 'Tổng hợp'. –

2

Một cách khác là thêm 0 vào nhóm để đảm bảo luôn có ít nhất một giá trị.

int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID) 
             .Select(c => c.Plays) 
             .Concat(new [] { 0 }) 
             .Sum(); 
Các vấn đề liên quan