2011-06-14 71 views
3

我有兩個表A和B.域對象拉動最從A其數據,並且從B.的LINQ:從多個表中選擇成一個預先定義的實體

一些聚合例如:

Table A (id, name); 
Table B (id_A, quantity); 

class A { 
    public int id { set; get; } 
    public string name { set; get; } 
} 
class B { 
    public int id_A { set; get; } 
    public int quantity { set; get; } 
} 

var result = 
from a in A join b in B on a.id equals b.id_A 
group b by b.id_A into g 
select new { 
    Name = a.name, 
    Total = g.Sum(b => b.quantity) 
}; 

而不是創建一個匿名類型,我想添加一個屬性域對象A稱爲TotalQuantity和填充它與g.Sum(b => b.quantity)。我也想把結果變成IEnumerable而不是var。

我的第一個賭注是

class A { 
    public int id { set; get; } 
    public string name { set; get; } 
    public int TotalQuantity { set; get; } 
} 

IEnumerable<A> result = 
from a in A join b in B on a.id equals b.id_A 
group b by b.id_A into g 
select new A { 
    name = a.name, 
    TotalQuantity = g.Sum(b => b.quantity) 
}; 

此操作不運行時支持:

System.NotSupportedException: Explicit construction of entity type 'Data.A' in query is not allowed. 

注意域A和B不包含對對方的任何引用。他們的關係沒有在應用程序中明確使用,因此我選擇不對它進行建模。

如何整齊地填充A的列表而不循環存儲在匿名類的實例中的數據?

回答

2

你必須在內存中執行的投影,而不是數據庫的。這樣LINQ to SQL提供程序就不會嘗試將其轉換爲SQL查詢。

下面是一個例子:

IEnumerable<A> result = (from a in A join b in B on a.id equals b.id_A 
         group b by b.id_A into g 
         select new 
         { 
          Name = a.name, 
          Total = g.Sum(b => b.quantity) 
         }) 
         .ToArray() 
         .Select(item => new A 
         { 
          Name = item.Name, 
          TotalQuantity = item.Total 
         }); 

IQueryable<T>.ToArray()方法將強制的LINQ to SQL供應商對數據庫運行查詢,並在數組中返回結果的調用。然後在內存中執行最後的預測,從而繞過LINQ to SQL提供程序的限制。

相關資源:

3

這應該這樣做(注意我沒有測試它這樣一些調整,可能是爲了):

IEnumerable <A> result = 
(from a in A join b in B on a.id equals b.id_A 
group b by b.id_A into g 
select new { 
    Name = a.name, 
    Total = g.Sum(b => b.quantity) 
}).Select(obj => new A {Name = obj.Name, TotalQuantity = obj.Total}); 
+0

您將需要添加'.AsEnumerable()'最後'Select'之前改變環境或否則你會得到相同的錯誤。 'ToList()'也可以。 – Equiso 2011-06-14 20:41:10