实体框架 - LinQ投影问题

时间:2010-12-10 11:46:36

标签: linq entity-framework

我想从LinQ语句创建一个实体对象,但我不想加载它的所有列。

我的ORDERS对象有很多列,但我只想检索REFERENCE和OPERATION列,这样SQL语句和结果就会更小。

此LinQ语句正常工作并加载我的所有对象属性:

var orders = (from order in context.ORDERS
             select order);

但是,以下语句无法仅加载我的对象的两个属性

 var orders = (from order in context.ORDERS
               select new ORDERS
               {
                    REFERENCE = order.REFERENCE,
                    OPERATION = order.OPERATION
               });

抛出的错误是:

  

实体或复杂类型   'ModelContextName.ORDERS'不能   在LINQ to Entities中构建   查询。

有什么问题?是不是可以用这种方式部分加载对象?

提前感谢您的回答。


ANSWER

好的,我应该感谢Yakimych和Dean,因为我使用了你的两个答案,现在我有了:

var orders = (from order in context.ORDERS
              select new
              {
                  REFERENCE = order.REFERENCE,
                  OPERATION = order.OPERATION, 
              })
              .AsEnumerable()
              .Select(o =>
                        (ORDERS)new ORDERS
                        {
                            REFERENCE = o.REFERENCE,
                            OPERATION = o.OPERATION
                        }
        ).ToList().AsQueryable();

我得到了我想要的东西,SQL语句并不完美,但它只返回我需要的2列(另一列包含每行“1”但我不知道为什么目前) - 我也尝试用这种方法构造子对象,效果很好。

3 个答案:

答案 0 :(得分:2)

不,您无法投影到映射对象。您可以改为使用匿名类型:

var orders = (from order in context.ORDERS
              select new
              {
                  REFERENCE = order.REFERENCE,
                  OPERATION = order.OPERATION
              });

答案 1 :(得分:2)

上述解决方案的问题在于,从调用AsEnumerable()的那一刻起,查询将在数据库上执行。在大多数情况下,它会没事的。但是,如果您使用某个大型数据库,则获取整个表(或视图)可能不是您想要的。因此,如果我们删除AsEnumerable,我们将回到方块1,并出现以下错误:

  

无法在LINQ to Entities查询中构造实体或复杂类型“ModelContextName.ORDERS”。

我一直在努力解决这个问题一整天,这就是我找到的。我创建了一个从我的实体类继承的空类,并使用这个类执行投影。

public sealed class ProjectedORDERS : ORDERS {}

预计查询(使用协方差特征):

IQueryable<ORDERS> orders = (from order in context.ORDERS
              select new ProjectedORDERS
              {
                  REFERENCE = order.REFERENCE,
                  OPERATION = order.OPERATION, 
              });

瞧!您现在有一个将映射到实体的预计查询,只有在您想要时才会执行。

答案 2 :(得分:0)

我认为问题是在查询本身中创建新实体,那么如何尝试:

context.ORDERS.ToList().Select(o => new ORDERS
{
    REFERENCE = o.REFERENCE,
    OPERATION = o.OPERATION
});