【问题标题】:EF Core Include ThenInclude FilterEF Core 包含 ThenInclude 过滤器
【发布时间】:2021-10-01 23:48:21
【问题描述】:

我有以下数据库结构

租户(一对多)-> 站点(一对多)-> SiteUrl

public sealed class Tenant : Entity
{
    public IReadOnlyCollection<Site> Sites => _sites?.ToList();
}

public class Site : Entity
{
    public IReadOnlyCollection<SiteUrl> Urls => _urls?.ToList();
}

我正在尝试使用 EF core 5.0 查询数据,并使用以下内容

var t = await tenants
                    .Include(t => t.Sites)
                    .ThenInclude(s => s.Urls.Where(su => su.Url == url))
                    .ProjectTo<TenantContextDto>(mapper.ConfigurationProvider)
                    .FirstOrDefaultAsync();

基本上,我试图根据网站的 url 获取租户,但我没有得到预期的结果。我已经尝试了代码的各种变体,但无法让它根据正在搜索的 url 找到正确的租户/站点。

任何帮助/建议将不胜感激

谢谢大家的回复

在我的数据库中 租户 1

当我搜索 localhost 时,我得到了正确的租户、正确的站点,但我得到了 url localhost1。

Gert Arnold:谢谢,完全忘记了投影忽略包括,那是一篇很棒的文章,你指点我谢谢。

【问题讨论】:

  • 返回的结果是什么?您可能还想向我们展示正在使用的 url 与存储在数据库中的内容。
  • 仅供参考,过滤Inlcude 与过滤查询不同,而且投影(几乎总是)忽略Includes。见here

标签: c# linq entity-framework-core


【解决方案1】:

如果您希望租户具有匹配的站点 URL,则:

var t = await tenants
    .Where(t => t.Sites.Any(s=> s.Url == url))
    .ProjectTo<TenantContextDto>(mapper.ConfigurationProvider)
    .FirstOrDefaultAsync();

Include/ThenInclude 用于当你想要返回一个实体并分别急切加载相关实体和它们各自的相关实体时。当使用 Automapper 的 ProjectTo 或使用 Linq 的 Select 时,不需要 Eager 加载,投影会根据需要加载数据。

如果您想将租户详细信息 (DTO) 中的站点过滤为仅与 URL 匹配的数据,则需要将您的投影配置为仅查找与条件匹配的记录。如果您的 DTO 在其中包含站点结构,它将包含匹配租户的所有站点,而不仅仅是具有目标 URL 的站点。

【讨论】:

    【解决方案2】:

    别忘了,沿着 1:M 关系走另一条路(从 M 到 1)要简单一些:

    context.SiteUrls.Where(su => su.Url == url).Select(su => su.Site.Tenant) ...
    

    【讨论】:

    • 看起来我们有一个赢家 - 倒退似乎是前进的方向:-)
    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 2021-10-28
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多