【问题标题】:Linq Expression Fails when I use OrderBy property.Length or mix Include,OrderBy and AutoMapper ProjectTo<T> Clause当我使用 OrderBy property.Length 或混合 Include、OrderBy 和 AutoMapper ProjectTo<T> 子句时,Linq 表达式失败
【发布时间】:2019-03-28 08:05:18
【问题描述】:

当使用 Include、Orderby 和 AutoMapper 的 ProjectTo&lt;T&gt; 子句组合的 LINQ 表达式时,Asp.net MVC Core 2.2 应用程序崩溃。以下是应用程序引发的异常:

无法转换类型的对象 'System.Linq.Expressions.PropertyExpression' 键入 'Remotion.Linq.Clauses.Expressions.QuerySourceReferenceExpression'。

此 LINQ 表达式的行为是不可预测的,因为有时它会起作用,而有时它会中断。我已经尝试过 Eager 和 Lazy 加载,但仍然出现相同的错误。

recordList = await db.SchoolProfile
                    .Include(i => i.Category)
                    .Include(i => i.District)
                    .Include(i => i.SchoolAddress.Address)
                    .Include(i => i.SchoolAddress.Coordinates)
                    .OrderBy(o => o.Name.Length)
                    .ProjectTo<SchoolProfileViewModel>(mapper.ConfigurationProvider)
                    .ToListAsync();

即使没有Include 子句也会抛出同样的错误:

recordList = await db.CurricularActivity
                    .OrderBy(o => o.Activity.Length)
                    .ProjectTo<CurricularActivityViewModel>(mapper.ConfigurationProvider)
                    .ToListAsync();

删除Activity.Length 似乎可行,但为什么它会破坏代码,但相同的查询在其他地方也有效?

因此,我希望得到一些解决此问题的指导。

我非常感谢了解为什么会发生这种情况并了解如何解决这个问题,以便我可以编写更高效且无错误的 LINQ 表达式

【问题讨论】:

  • 很可能是 EF Core 问题。检查the execution plan。将其作为 LINQ 语句运行,无需 AM。你应该得到相同的结果。
  • @LucianBargaoanu 感谢您的链接,执行顺序有影响,所以我将查询更改为先进行投影,然后再进行 LINQ 表达式,它按预期工作。

标签: asp.net-core entity-framework-core ef-core-2.2 automapper-collections-ef-core


【解决方案1】:

显然,表达的顺序最重要,我的工作没有错误@Lucian Bargaoanu,感谢您提供link to automapper 文档。始终以 Projection 开头,使用ProjectTo&lt;T&gt;,后跟LINQ 表达式。

recordList = await db.SchoolProfile
                    .ProjectTo<SchoolProfileViewModel>(mapper.ConfigurationProvider)
                    .OrderBy(o => o.SchoolName)
                    .ToListAsync();

【讨论】:

  • 在 EF6 中,它可以在没有 Include-s 的情况下工作。我不确定 EF Core,但试试看 :)
  • @LucianBargaoanu 我认为 EF6 默认打开了延迟加载,而 EF-Core 并非如此,使用 ef-core 您需要添加 Microsoft.EntityFrameworkCore.Proxies 包并激活它在 DBcontext 选项上的 ConfigureServices 中全局设置如下:options.UseLazyLoadingProxies 或使用上下文实例将其打开和关闭,如下所示:dbcontext.ChangeTracker.LazyLoadingEnabled = 布尔值。所以现在,使用 Includes 的 EagerLoading 对我来说是一个方便的选择。
  • 这里不涉及延迟加载。看执行计划。默认情况下,ProjectTo 将获取视图模型中的所有内容。这就是不需要 Include 的原因。
  • 除非您实际映射到包含真实数据库实体类型的类型,否则那些 Include() 调用实际上不会做任何事情,因此您可以摆脱它们。不知道为什么如果您按特定顺序使用它们会损坏。
  • 感谢您的友好反馈,我可以确认它可以在没有 Include() 子句的情况下工作,但是当我执行 .OrderBy(o =&gt; o.SchoolName.Length) 时会引发错误。如果我删除 .Length 它就可以了。所以我仍然对此感到困惑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多