Linq:从多个表中选择一个预定义的实体
本文关键字:一个 预定义 实体 选择 Linq | 更新日期: 2023-09-27 17:59:13
我有两个表A和B。域对象从A提取大部分数据,从B提取一些聚合。
例如:
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列表?
这应该可以做到(注意,我还没有测试过,所以可能需要进行一些调整):
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});
您将需要在内存中而不是在数据库中执行投影。这样,LINQ到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到SQL提供程序对数据库运行查询,并在数组中返回结果。然后在内存中执行最后的投影,从而避开了LINQ到SQL提供程序的限制。
相关资源:
- LINQ和延迟执行
- IEnumerable与IQueryable的性能影响