【问题标题】:Many to Many using LinqKit with EF Core with Generic class多对多使用带有通用类的 EF Core 的 LinqKit
【发布时间】:2019-12-28 00:15:06
【问题描述】:

我目前正在将一个 EF 项目转换为 EF Core,但我不知道如何或是否可以:

a) 在带有 EF Core 的多对多上使用 LinqKit

b) 将 a) 与泛型类一起使用

我目前正在使用以下课程:

    protected virtual IQueryable<TEntity> GetQueryable(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = null,
        bool isCollection = false,
        int? skip = null,
        int? take = null)
    {
        IQueryable<TEntity> query = this.Context.Set<TEntity>();

        if (filter != null)
        {
            query = query.AsExpandable().Where(filter);
        }

        if (includeProperties != null)
        {
            foreach (var includeProperty in includeProperties.Split
                (new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }
        }

        if (orderBy != null)
        {
            query = orderBy(query);
        }

        if (skip.HasValue)
        {
            query = query.Skip(skip.Value);
        }

        if (take.HasValue)
        {
            query = query.Take(take.Value);
        }

        return query;
    }

在 EF 6 中,我会将泛型类的类型设置为我想要处理的主实体,如果它有多对多,我只需将 IncludeProperties 设置为子实体。

例如:

var test = GetQueryable<Company>(null, "Users");

这将返回所有公司并返回与每个相关公司关联的所有用户。

LinqKit 然后会进来添加额外的过滤器、订单等......

但我不知道如何在 EF Core 中使用多对多关系。

我看过一个例子,你做了类似的事情:

this.Context.Companies.Include("CompanyUsers")
                      .ThenInclude("Users")
                      .ToListAsynch()

上面看起来像我需要的,但我需要使用它是通用的,我需要使用 LinqKit 或其他方式应用过滤器,但我需要动态设置过滤器、排序、分页等。

有什么想法吗?

谢谢

UPDATE-1:

我的多对多关系类定义如下:

public class CompanyUsers
{
    public Guid UserId { get; set; }

    public User User { get; set; }

    public Guid CompanyId { get; set; }

    public Company Company { get; set; }
}

我添加它的原因是,虽然我的用户表称为“用户”,但导航属性称为用户,正如 Dennis 所建议的那样,我应该指定多对多类 (CompanyUsers),然后是导航属性(用户)所以而不是:

var test = GetQueryable<Company>(null, "CompanyUsers.Users");

它应该被定义为:

var test = GetQueryable<Company>(null, "CompanyUsers.User");

请注意,s 已被删除以匹配导航属性而不是表格。

【问题讨论】:

  • 最简单的解决方案是在 Include 上使用基于字符串的重载,如下所示:var test = GetQueryable&lt;Company&gt;(null, "CompanyUsers.Users");
  • @Dennis1679 很有趣...从来没想过。现在无法尝试,但会在几天后回来,然后会更新您。谢谢
  • @Dennis1679 这行得通。完成后,我只需重新调整我的 AutoMapper 配置文件,使用来自 CompanyUsers 的集合,并在从实体转换为模型时将其用户导航属性映射到用户(模型)的集合。再次感谢。
  • 哦,你会创建这个作为答案让它更正式,所以我可以接受。谢谢。
  • 你去@Thierry

标签: c# entity-framework entity-framework-core


【解决方案1】:

最简单的解决方案是使用Include.*的字符串重载

var test = GetQueryable<Company>(null, "CompanyUsers.User");

*我不推荐使用魔术字符串。您应该考虑编写一个基于模型属性返回 this 的方法。

【讨论】:

  • 您的答案的其他要点:1)按照您的建议更改我使用 LinqKit 的方式,b)使用多对多类作为导航的一部分,我不知道您可以这样做.至于魔线,绝对是。这是我试图在没有额外复杂性的情况下首先解决这个问题。再次感谢。
猜你喜欢
  • 2021-08-19
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 2020-07-14
  • 1970-01-01
相关资源
最近更新 更多