【问题标题】:Using methods inside EF Core queries在 EF Core 查询中使用方法
【发布时间】:2020-04-11 07:00:24
【问题描述】:

我使用 EF 和 EF Core 已经有很长时间了,但总有一些问题一直给我带来问题,无论是哪种方式,那就是在查询中使用方法,特别是在映射时。

例如,现在我有这个代码

    public IEnumerable<SelectObjDTO> SelectSearch()
    {
        return Context.Usuarios.IncludePerson().ToSelectObjDTO();
    }

在不同的班级

    public static IQueryable<Users> IncludePerson(this IQueryable<Usuers> Query)
    {
        return Query.Include(x => x.Persons );
    }

    public static SelectObjDTO ToSelectObjDTO(this Persons POCO)
    {
        return new SelectObjDTO()
        {
            Id = POCO.Users.FirstOrDefault().Id,
            FirstName= POCO.DocumentNumber+ " - " + POCO.FirstName + " " + POCO.LastName
        };
    }

    public static IEnumerable<SelectObjDTO> ToSelectObjDTO(this IEnumerable<Persons> Query)
    {
        return Query.Select(POCO => POCO.ToSelectObjDTO());
    }

函数IEnumerable&lt;SelectObjDTO&gt; ToSelectObjDTO(this IEnumerable&lt;Persons&gt; Query) 返回错误,因为Users 为空。

但在IEnumerable&lt;SelectObjDTO&gt; ToSelectObjDTO(this IEnumerable&lt;Persons&gt; Query) 中,查询确实在Users 列表中包含某些内容。

这是这种情况,但在我遇到其他问题之前,例如来自 EF Core 的错误,它基本上表示上下文在同一个查询中运行了两次(真的很抱歉,记不清了它是怎样的),这是通过包含正在调用的任何导航属性来修复的。

以防万一,我正在使用延迟加载代理。

谢谢

【问题讨论】:

  • 在处理变量之前将其加载到内存中。
  • 如果我将它加载到内存中,查询将加载完整的实体,而不是只加载我需要的内容

标签: c# asp.net .net-core entity-framework-core ef-core-2.2


【解决方案1】:

ToSelectObjDTO 是一个编译函数。您需要将Expression&lt;Func&lt;...&gt;&gt; 作为参数传递给Select()。如果需要,您仍然可以将其编译用于其他用途。

    public static Expression<Func<Persons,SelectObjDTO>> SelectorFunc { get; } = POCO =>
        new SelectObjDTO()
        {
            Id = POCO.Users.FirstOrDefault().Id,
            FirstName= POCO.DocumentNumber+ " - " + POCO.FirstName + " " + POCO.LastName
        };

    public static Func<Persons,SelectObjDTO> Selector  { get; } = SelectorFunc.Compile();

    public static IQueryable<SelectObjDTO> ToSelectObjDTO(this IQueryable<Persons> Query)
        => Query.Select(SelectorFunc);

【讨论】:

  • ToSelectObjDTO 给我一个错误说“IEnumerable 不包含'Select'的定义”(不知道为什么)。不过,如果我使用 IQueryable 而不是 IEnumerable 就可以工作,但我有点需要它在 IEnumerable 中工作,所以我可以在两种情况下都使用它
  • @JavierGoldman 因为您不能在这样的 linq 语句上运行内存操作,所以它不知道如何将其转换为 sql。这就是为什么我建议在内存中使用它。
  • @Train 如果我在语句中使用操作而不调用其他函数,它可以完美运行。如果我用 IQueryable 执行 Jeremy 所说的相同(这仍然是一个查询,所以它不在内存中)。IQueryable 继承自 IEnumerable 所以我不明白为什么它不能那样工作。我可能错了,但据我所知,仅从数据库中获取所需的列对于 EF 查询中的性能非常重要。特别考虑到我从用户实体获取数据,如果我不这样做,我不仅会获取整个 Persons 实体数据,还会获取相关用户的所有数据
  • 糟糕,IQueryable。更新。当然,您可以在 IEnumerable 上使用已编译的选择器。
  • 我在第一条评论中的意思是我想在 IEnumerable 中使用它,但不能,因为我收到此错误:'IEnumerable' 不包含'Select'的定义和最好的扩展方法重载 'Queryable.Select(IQueryable, Expression>)' 需要 'IQueryable' 类型的接收器 编辑:我的错,我试过用的不是编译好的。我正在尝试像以前一样使用 ToSelectObjDTO(在参数和返回类型中都使用 IEnumerable)
猜你喜欢
  • 2021-02-22
  • 2018-04-04
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 2021-05-03
  • 2019-12-17
相关资源
最近更新 更多