2017-02-22 143 views
1

我使用的是实体框架核心,下面是Chris Sakell的博客here实体框架核心 - 同时包含相关实体的加载相关实体的问题

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

基础知识库的一部分具有以下代码,用于检索单个实体,该实体也使用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); 

成功检索的创造者和国家工作值。

但是,没有为与“工作”相关联的相关实体检索到任何东西。

enter image description here

在particuar,JobVisits是参观作业的集合。

为了完整性我加入了“工作”和“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使用,这样我也可以加载相关enbities JobVisit collection和其他相关单实体BrandJobType

回答

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(); 
}