Why does EF throw an error with LastOrDefault in Include operations but not with OrderByDescending?

huangapple go评论74阅读模式
英文:

Why does EF throw an error with LastOrDefault in Include operations but not with OrderByDescending?

问题

我需要从Monitoring表中获取最后一条记录。

return await _context.Applications
                .Include(s => s.Elements)
                .ThenInclude(d => d.Monitoring.LastOrDefault())
                .ToListAsync();

但是 EF 抛出了一个错误:

System.InvalidOperationException: 表达式 's.Elements.AsQueryable().LastOrDefault()'  'Include' 操作中无效,因为它不代表属性访问:'t => t.MyProperty'。
要针对派生类型上声明的导航属性,请使用强制转换('t => ((Derived)t).MyProperty')或 'as' 运算符('t => (t as Derived).MyProperty')。
集合导航访问可以通过组合 WhereOrderByDescending)、ThenByDescending)、Skip  Take 操作进行过滤。

但是,当我使用OrderByDescending执行相同的请求时,它可以正常工作。

return await _context.Applications
                .Include(s => s.Elements)
                .ThenInclude(d => d.Monitoring.OrderByDescending(c => c.Id))
                .ToListAsync();

有人能解释一下使用OrderByDescendingLastOrDefault之间的区别吗?

在这种情况下,如何正确获取最后一项?

英文:

I need to get the last record from the Monitoring table

return await _context.Applications
                .Include(s => s.Elements)
                .ThenInclude(d => d.Monitoring.LastOrDefault())
                .ToListAsync();

But EF throw an error :

System.InvalidOperationException: The expression 's.Elements.AsQueryable().LastOrDefault()' is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'. 
To target navigations declared on derived types, use casting ('t => ((Derived)t).MyProperty') or the 'as' operator ('t => (t as Derived).MyProperty'). 
Collection navigation access can be filtered by composing Where, OrderBy(Descending), ThenBy(Descending), Skip or Take operations.

But when I execute the same request with OrderByDescending it works fine.

return await _context.Applications
                .Include(s => s.Elements)
                .ThenInclude(d => d.Monitoring.OrderByDescending(c => c.Id))
                .ToListAsync();

Can anyone explain what is the difference between using OrderByDescending and LastOrDefault?

How would it be correct to get the last item in this case?

答案1

得分: 2

以下是您要翻译的内容:

区别在于对其中一个的支持已经实现,而对另一个则没有。这在 EF Core 文档中有记录,关于Filtered Include的部分:

> 支持的操作包括:WhereOrderByOrderByDescendingThenByThenByDescendingSkipTake

因此,您可以执行以下操作:

return await _context.Applications
    .Include(s => s.Elements)
    .ThenInclude(d => d.Monitoring.OrderByDescending(c => c.Id).Take(1))
    .ToListAsync();

这将导致 Monitoring 最多只有一个具有最大 Id 的元素。

英文:

The difference is that support for one is implemented and for another - is not. This is documented in the EF Core docs for Filtered Include:

> Supported operations are: Where, OrderBy, OrderByDescending, ThenBy, ThenByDescending, Skip, and Take.

So you can do:

return await _context.Applications
    .Include(s => s.Elements)
    .ThenInclude(d => d.Monitoring.OrderByDescending(c => c.Id).Take(1))
    .ToListAsync();

Which should result in Monitoring having at most one element with largest Id.

答案2

得分: 0

以下是您要翻译的内容:

异常描述了您的问题几乎完美。
IncludeThenInclude 无法接受一个 object,这是 LastOrDefault() 的结果。

当您调用 OrderByDescending 时,它仍然是一个属性访问器,可以被 EF 转换为 SQL 代码 - 同时,它是集合的指针。

尝试将您的代码直接转换为 SQL 代码,您如何执行 "JOIN" 操作与单行(这就是 LastOrDefault 尝试执行的操作)? - 你不能。

LastOrDefaultOrderByDescending 之间的区别在于,第一个结果是一个记录,而另一个结果是一个按您的喜好排序的集合。

英文:

The exception describes your problem almost perfectly.
Include or ThenInclude can't accept an object, which is a result of LastOrDefault().

When you you call OrderByDescending instead, it's still a property accessor which can be converted by EF to the SQL code - also, it's a pointer to the collection.

Try to convert your code directly to the SQL code, how can you perform "JOIN" with a single row (this is what LastOrDefault tries to perform) ? - you can't.

The difference between LastOrDefault and OrderByDescending is that first one, results in a single record, and another one results in a collection, ordered by your preference.

huangapple
  • 本文由 发表于 2023年5月25日 18:04:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76331084.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定