【问题标题】:Cannot map LINQ to Entities无法将 LINQ 映射到实体
【发布时间】:2017-03-16 14:26:19
【问题描述】:

我对编写 linq 查询不是很清楚。我使用 linq lambda 表达式编写了一个查询以仅从表中选择某些列,并且我得到了无法将 linq 构造为实体的错误。当我使用 linq 编写相同的查询来选择所有列时,我没有收到任何错误,并且我得到了所有列,我稍后在视图中将其过滤掉。但我想使用 lambda 仅选择某些列。

代码sn-p:

视图模型:

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 吗?我不确定数据传输对象的用途是什么。对此进行一些解释会很棒。谢谢。

【问题讨论】:

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


    【解决方案1】:

    您需要使用 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
         });
    

    【讨论】:

    • 谢谢,我想我有点想法了,打算试试。我的视图模型有一个 IEnumerable。那么我可以创建该视图模型的对象并对其进行映射。就像 app.StaggingInnlaCashException=the 查询一样。对吗?
    • 您需要创建一个 StaggingInternalExceptionViewModel 然后在查询上使用 Select 就像在答案中一样,唯一的区别是在答案中它被称为 StaggingInternalExceptionDTO 而不是 StaggingInternalExceptionViewModel
    • 不应该是 IEnumerable StaggingInternalExceptionDTO。我想要一个 StagingInternalException 类的列表。公共 IEnumerable StaggingInternalException { 获取;放; }
    • 添加 .ToList(),在选择 ...ExternalAmount = i.ExternalAmount }).ToList() 之后,如果你不调用 .ToList() 它实际上并没有发出请求到数据库,因此是 IQueryable 类型
    【解决方案2】:

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

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

    【讨论】:

    • 我不能在这里使用匿名类型,因为我得到错误,它不能将通用匿名类型隐式转换为通用 IEnumerbable 类型。所以我认为只有 DTO 在这里工作?
    • 是的,你需要一个强类型,所以,用你需要的属性定义一个类并在它上面投影,并改变你的方法的返回类型,例如;IEnumerbable&lt;StaggingInternalCashExceptionDTO&gt;
    • 我刚刚编辑了我的问题。我添加了视图模型,我该怎么做})。我得到的错误是不能将 IQueryable 类型隐式转换为 IEnumerable。但我认为它默认返回 IEnumerable 中的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多