正如EF-Core中眾所周知的那樣,沒有延遲加載。所以這種方式我不得不在事後做一些事情。所以,既然我必須思考,那麼我不妨嘗試正確地做到這一點。

我有一個相當標準的更新查詢,但我認為嘿,我並不總是要包含HeaderImagePromoImage FK對象。應該有辦法實現這一目標。但我可能無法在以後找到一種方法來執行Include。實際上我想在我真正開始研究這個對象之前就可以包含它。這樣我就可以自動化一些渴望。

ArticleContent ac = _ctx.ArticleContents
    .Include(a=> a.Metadata)
    .Include(a=> a.HeaderImage)
    .Include(a=> a.PromoImage)
    .Single(a => a.Id == model.BaseID);

ac.Title = model.Title;
ac.Ingress = model.Ingress;
ac.Body = model.Body;
ac.Footer = model.Footer;

if (model.HeaderImage != null)
{
    ac.HeaderImage.FileURL = await StoreImage(model.HeaderImage, $"Header_{model.Title.Replace(" ", "_")}_{rand.Next()}");
}
if (model.PromoImage != null)
{
    ac.PromoImage.FileURL = await StoreImage(model.PromoImage, $"Promo_{model.Title.Replace(" ", "_")}_{rand.Next()}");
}

ac.Metadata.EditedById = uId;
ac.Metadata.LastChangedTimestamp = DateTime.Now;

await _ctx.SaveChangesAsync();

額外

要明確的是,這是EF7(Core) ,並且我在一個允許我按需添加的解決方案之後,希望在最初的_ctx.ArticleContents.Include(a=> a.Metadata).Single(a => a.Id == model.BaseID).

熱門答案

我正在使用類似Alexander Derck的解決方案。 (關於評論中提到的例外:ctx.ArticleContents.AsQueryable()也應該有效。)

對於幾個CRUD MVC站點,我正在使用BaseAdminController 。在派生的具體控制器中,我可以動態添加包含。從BaseAdminController:

// TModel: e.g. ArticleContent
private List<Expression<Func<TModel, object>>> includeIndexExpressionList = new List<Expression<Func<TModel, object>>>();

protected void AddIncludes(Expression<Func<TModel, object>> includeExpression)
{
    includeIndexExpressionList.Add(includeExpression);
}

後來我發現我需要更多的靈活性,所以我添加了一個可查詢的。例如,對於ThenInclude()。

private Func<IQueryable<TModel>, IQueryable<TModel>>  IndexAdditionalQuery { get; set; }

protected void SetAdditionalQuery(Func<IQueryable<TModel>, IQueryable<TModel>> queryable)
{
    IndexAdditionalQuery = queryable;
}

這裡的索引動作:

public virtual async Task<IActionResult> Index()
{
    // dynamic include:
    // dbset is for instance ctx.ArticleContents
    var queryable = includeIndexExpressionList
        .Aggregate(dbSet.AsQueryable(), (current, include) => current.Include(include));
    if(IndexAdditionalQuery != null) queryable = IndexAdditionalQuery(queryable);
    var list = await queryable.Take(100).AsNoTracking().ToListAsync();
    var viewModelList = list.Map<IList<TModel>, IList<TViewModel>>();

    return View(viewModelList);
}

在具體的控制器我使用:

AddIncludes(e => e.EventCategory);

SetAdditionalQuery(q => q
    .Include(e => e.Event2Locations)
    .ThenInclude(j => j.Location));


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow