2017-02-22 181 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(); 
}