将表添加到现有LINQ查询

时间:2013-01-07 18:10:14

标签: c# asp.net-mvc linq

我有一个问题:

model.Queue = _db.Orders
                .Join(_db.Tool,
                    a => a.PART_KEY,
                    b => b.PART_KEY,
                    (a, b) => new { a, b })
                .Where(r => (r.a.PART_KEY == r.b.PART_KEY) && (r.b.Site == Site))
                .Where(r => (r.a.Start > 0) && (r.a.Finish == 0))
                .GroupBy(r => new { r.a.GROUP })
                .Select(r => new Queue
                {
                    name = r.Key.GROUP,
                    count = r.GroupBy(g => g.a.PART_KEY).Count(),
                    average = r.Average(g => g.a.DaysInSequence)
                });

该查询目前用于为用户生成指标。用户现在希望扩展指标以包含表OrdersCompleted中已完成的订单。在数据库中,订单完成后,整个订单将从Orders移至OrdersComplete。两个表都具有相同的结构,即相同的列和相同的模型类。

看起来我需要使用的扩展方法是Concat,但我遇到的问题是找出使其适用于此特定查询的语法。似乎添加.Concat(_db.OrdersComplete)作为第一个扩展方法应该起作用,但似乎并非如此。

2 个答案:

答案 0 :(得分:2)

问题在于即使两个表具有完全相同的列和完全相同的类型和名称,生成类的工具也会创建两个具有不同名称的类型。由于类型不是完全相同,Concat将无效。您需要做一些事情来映射一个或两个表,以便它们共享一个类型。

一种选择是将它们都映射到匿名类型。添加如下内容:

.Select(o => new
{
    o.PART_KEY,
    o.GROUP
    //Any other columns you need from each order
});

同时_db.Orders以及_db.OrdersComplete。然后Concat将起作用。

另一种选择,如果您认为需要处理所有组合订单的常见问题,那就是解决数据库类不相关的基本问题。您可以修改实际的DB对象,以便在所有查询中更轻松。

一种选择是创建两个类都可以扩展/实现的接口或基类型。如果您创建一个包含两个类型共享的所有列的接口,并让它们都实现该接口,那么您可以使用Concat创建该接口的枚举。 (不知道Linq-To-Sql会有多好。)

第三种选择是在数据库中创建一个View,在这两个表上只有Union All,可能会从一个或两个表中拉出一部分列。然后,您可以查询该视图,而不是自己对表进行查询。

答案 1 :(得分:0)

Servy的answer是正确的:最简单的方法是从两个查询中的每个查询中创建一个匿名类。只要匿名类具有相同的属性,ConcatUnion都将起作用。

一种可能的替代方法是在两个表上运行相同的查询(因为您已将结果投影到新的Queue对象中,并Concat来自两个查询的结果。