【问题标题】:Entity Framework Core - issue with loading related entities that also contain related entitiesEntity Framework Core - 加载也包含相关实体的相关实体的问题
【发布时间】:2017-02-23 16:52:08
【问题描述】:

我在 Chris Sakell 的博客 here 之后使用 Entity Framework Core。

他使用泛型来管理他的存储库以及他用于所有其他存储库的基本存储库。

基础存储库的一部分具有以下代码,用于检索单个实体,该实体还使用includeProperties 选项下载相关实体。这是检索单个项目的通用代码。

public T GetSingle(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable<T> query = _context.Set<T>();

    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
    }

    return query.Where(predicate).FirstOrDefault();
}

我在附有许多作业的客户端表上使用它。

这就是我构建代码的方式。

    public ClientDetailsViewModel GetClientDetails(int id)
    {
        Client _client = _clientRepository
            .GetSingle(c => c.Id == id, c => c.Creator, c => c.Jobs, c => c.State);

        if(_client != null)
        {
            ClientDetailsViewModel _clientDetailsVM = mapClientDetailsToVM(_client);
            return _clientDetailsVM;
        }
        else
        {
            return null;
        }
    }

行:

.GetSingle(c => c.Id == id, c => c.Creator, c => c.Jobs, c => c.State);

成功检索创建者状态和作业的值。

但是,对于与“作业”关联的那些相关实体,不会检索任何内容。

特别是,JobVisits 是工作访问的集合。

为了完整起见,我在下面添加了“job”和“jobvisit”实体

public class Job : IEntityBase
{
    public int Id { get; set; }

    public int? ClientId { get; set; }
    public Client Client { get; set; }

    public int? JobVisitId { get; set; }
    public ICollection<JobVisit> JobVisits { get; set; }

    public int? JobTypeId { get; set; }
    public JobType JobType { get; set; }

    public int? WarrantyStatusId { get; set; }
    public WarrantyStatus WarrantyStatus { get; set; }

    public int? StatusId { get; set; }
    public Status Status { get; set; }

    public int? BrandId { get; set; }
    public Brand Brand { get; set; }

    public int CreatorId { get; set; }
    public User Creator { get; set; }

    ....
}

public class JobVisit : IEntityBase
{
    ...
    public int? JobId { get; set; }
    public Job Job { get; set; }

    public int? JobVisitTypeId { get; set; }
    public JobVisitType VisitType { get; set; }
}

我的问题是,如何修改上面的存储库代码和我的GetSingle 使用,以便我还可以加载相关实体JobVisit 集合和其他相关的单个实体BrandJobType

【问题讨论】:

    标签: entity-framework-core


    【解决方案1】:

    不需要检索导航属性来与“作业”相关联。这就是为什么有些属性是null。默认情况下,.Include(property); 只有 1 级深度,这是一件好事。它会阻止您的查询获取数据库的所有数据。

    如果你想包含多个级别,你应该在.Include(property)之后使用.ThenInclude(property)。来自documentation

    using (var context = new BloggingContext())
    {
        var blogs = context.Blogs
            .Include(blog => blog.Posts)
                .ThenInclude(post => post.Author)
            .ToList();
    }
    

    我的建议是你的方法public T GetSingle(...) 很好,我不会为了包含更深层次而改变它。取而代之的是,您可以简单地使用显式加载。来自documentation

    using (var context = new BloggingContext())
    {
        var blog = context.Blogs
            .Single(b => b.BlogId == 1);
    
        context.Entry(blog)
            .Collection(b => b.Posts)
            .Load();
    
        context.Entry(blog)
            .Reference(b => b.Owner)
            .Load();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 1970-01-01
      • 2016-10-10
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 2018-09-10
      相关资源
      最近更新 更多