无法将LINQ映射到实体

时间:2017-03-16 14:26:20

标签: asp.net-mvc entity-framework linq lambda dto

我不太清楚编写linq查询。我编写一个查询,只使用linq lambda表达式从表中选择某些列,我得到了linq无法构造给实体的错误。当我使用linq编写选择所有列时,同样的查询我没有得到任何错误,我得到所有列,我稍后在视图中过滤掉。但是我想使用lambda来只选择某些列。

代码段:

视图模型:

public class StaggingInternalCashExceptionViewModel
    {



        public OutputCash OutputCash { get; set; } 
        public IEnumerable<StaggingInternalException> StaggingInternalException { get; set; }
        //list of results of Stagginginternalcashexception
    }

控制器:

 public ActionResult Exceptionstest(string dd1, string dd2, string dd3)
{
     StaggingInternalExceptionViewModel _app = new StaggingInternalExceptionViewModel();

_app.StaggingInternalException = db2.StaggingInternalExceptions.Where(x => x.Level1 == dd1 && x.Level2 == dd2 ).Select(i => new StaggingInternalException
         {


             StaggingInternalRowID = i.StaggingInternalRowID,
             Category = i.Category,
             EnterText1 = i.EnterText1,
             InternalAmount = i.InternalAmount,
             ExternalAmount = i.ExternalAmount

         });

  _app.StaggingInternalException = (from p in db2.StaggingInternalExceptions 
                                                 where p.LoadID==loadid && p.Level1 == dd1 && p.Level2 == dd2   select p);
}

在上面的代码中,lambda表达式在我尝试仅从表中选择某些列时,或者如果我们是按实体类来说,只是某些属性时会抛出错误。但查询返回所有列。我应该使用DTOS吗?我不确定数据传输对象的用途是什么。对此的一些解释会很棒。感谢。

2 个答案:

答案 0 :(得分:2)

您需要使用DTO。 dto只是您将结果映射到的对象。在你的情况下,它将是

public class StaggingInternalExceptionViewModel
{
     public int StaggingInternalRowID { get; set; }
     public int Category { get; set; }
     ... //rest of properties
}

您需要更改StaggingInternalCashExceptionViewModel以使用StaggingInternalException DTO

public class StaggingInternalCashExceptionViewModel
{
    public OutputCash OutputCash { get; set; } 
    public IEnumerable<StaggingInternalExceptionViewModel> StaggingInternalException { get; set; }
    //list of results of Stagginginternalcashexception
}

然后你的表达式保持基本相同,但你选择了一个新的StaggingInternalExceptionViewModel而不是StaggingInternalException

StaggingInternalExceptionViewModel _app = new StaggingInternalCashExceptionViewModel();

_app.StaggingInternalException = db2.StaggingInternalExceptions.Where(x => x.Level1 == dd1 && x.Level2 == dd2 ).Select(i => new StaggingInternalExceptionViewModel
     {
         StaggingInternalRowID = i.StaggingInternalRowID,
         Category = i.Category,
         EnterText1 = i.EnterText1,
         InternalAmount = i.InternalAmount,
         ExternalAmount = i.ExternalAmount
     });

答案 1 :(得分:1)

Linq to Entities不允许您使用实体类型投影查询,因为您最终可能会在部分加载实体时丢失信息并稍后尝试将该实体保存到您的数据库中。因此,当您需要实体的部分信息时,无论是使用DTO还是anonymous type,都必须投影查询。

如果你需要使用实体类型,那么不要使用Select方法进行投影,唯一的是你要加载所有的属性,但我认为情况并非如此,因为你不要不需要所有数据;)。