当我尝试在查询中调用扩展方法时,Entity Framwork Core 无法检索数据

问题描述 投票:0回答:1

当我有以下 EF 查询时,无法从数据库检索数据。

var results = await (from a in agreements
                        let showPasscode = <snipped>
                        let passcode = <snipped>
                        select new Result(
                            a.Id,
                            a.UserId,
                            a.CurrentCycle().StartsOn,
                            passcode,
                            showPasscode)
                        )
                        .ToListAsync(cancellationToken);

以及

CurrentCyle

的代码
public static AgreementCycle CurrentCycle(this Agreement agreement) => 
    agreement.Cycles
        .OrderByDescending(x => x.StartsOn)
        .FirstOrDefault();

现在,当我在扩展方法中运行它(并放置断点)时,我得到以下结果:

现在我知道数据库-确实-具有该项目的链接数据。

猜测这可能与一些延迟表达式处理有关?就像,扩展方法在执行数据库结果之后运行并且属性尚未“包含”或其他什么?

如果我手动添加扩展方法的内容,我会得到正确的结果:

var results = await (from a in agreements
                        let showPasscode = <snipped>
                        let passcode = <snipped>
                        select new Result(
                            a.Id,
                            a.UserId,
                            a.Cycles.OrderByDescending(c => c.StartsOn).FirstOrDefault().StartsOn, // <-- HERE
                            passcode,
                            showPasscode)
                        )
                        .ToListAsync(cancellationToken);

所以我不确定需要做什么。现在,如果这都是关于缺少“Include(..)”语句的问题..这可能不起作用,因为请注意我的查询的格式 - 它就像旧的 linq-to-sql 格式。为什么?因为那些 2x

let
命令。我喜欢这些,它确实帮助我使我的查询更容易/更简单。我不确定我能以任何方式做到这一点吗?

c# entity-framework entity-framework-core
1个回答
0
投票

您是否启用了客户端评估,并且您是否看到任何有关客户端评估与原始查询一起使用的警告?

扩展方法通常不适用于 EF,除非您打开了客户端评估,因为扩展方法无法转换为 SQL。我怀疑这是一种情况,您正在运行客户端评估,但禁用了延迟加载,因此当客户端针对 Cycles 执行时,集合为空。

这可能可以通过急切加载周期 /w

Include(x => x.Cycles)
来解决,但这通常并不理想,因为它会扩大返回的数据足迹大小。这也可以通过启用延迟加载来解决,但这几乎不是一个好的解决方案,因为使用集合时会影响性能。

您所做的手动提取确实是正确的解决方案。如果您想要一种更简洁的方式在一个地方执行此操作,请考虑使用与 EF 的

IQueryable
实现配合使用的映射器。通过这种方式,您可以配置如何转换实体 -> 结果 DTO 以及映射规则(例如最新的 StartsOn)可以驻留在映射中。例如 Automapper 支持
ProjectTo<TDestination>()
。 (https://docs.automapper.org/en/stable/Queryable-Extensions.html

© www.soinside.com 2019 - 2024. All rights reserved.