【问题标题】:Linq: select from multiple tables into one pre-defined entityLinq:从多个表中选择一个预定义的实体
【发布时间】:2011-06-14 20:27:37
【问题描述】:

我有两个表 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 列表?

【问题讨论】:

    标签: c# .net linq linq-to-sql linq-to-entities


    【解决方案1】:

    应该这样做(注意我没有测试它,所以可能需要进行一些调整):

    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});
    

    【讨论】:

    • 您需要在最后一个 Select 之前添加 .AsEnumerable() 以更改上下文,否则您将收到相同的错误。 ToList() 也可以。
    【解决方案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 提供程序的限制。

    相关资源:

    【讨论】:

      猜你喜欢
      • 2013-01-25
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多