3

EFコアでよく知られているように、レイジーローディングはありません。そのような意味で、私はいくつかの後から考えて質問しなければなりません。だから私は考えなければならないので、それを正しくやろうとするかもしれない。条件付きで含めると次に含む

私はかなり標準的な更新クエリを持っていますが、私はいつも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(); 

EXTRA

明確にするために、これはEF7(コア)で、私は追加することができます解決後のIMがうまくいけば、最初の_ctx.ArticleContents.Include(a=> a.Metadata).Single(a => a.Id == model.BaseID).

+0

私はあなたが「あなたの後にそれを行うことができるようになるだろうとは思いませんこれは単一点と呼ばれます。これは、指定されたすべてのインクルードを考慮に入れて、オブジェクトをデータベースからメモリに実体化します。実際に読み込んだデータの上に追加のデータを取り込むようにフレームワークに依頼することができたら(つまり、レイジーローディングを熱心なローディングアプローチに強制しようとしている) –

+0

@MikeGoatlyはい、私は私の夢の解決策は熱心な読み込みと怠惰な読み込みのハイブリッドになるでしょう。本当に私の夢に最適な解決策になる 'IncludeIf(a => a.PromoImage、true | false) 'のようなものが存在するはずです –

答えて

0

た後、必要に応じて含み私は、式としてインクルードするプロパティを取るデータを取得するメソッドを作成します。

static ArticleContent GetArticleContent(int ID, 
    params Expression<Func<ArticleContent, object>>[] includes) 
{ 
    using(var ctx = new MyContext()) 
    { 
     var acQuery = _ctx.ArticleContents.Include(a=> a.Metadata); 
     foreach(var include in includes) 
     acQuery = acQuery.Include(include); 
     return acQuery.Single(a => a.Id == model.BaseID); 
    } 
} 

そして、mainメソッドに:

var ac = GetArticleContent(3, a => a.HeaderImage, a => a.PromoImage); 
+0

うん、それは私が望んでいたものにかなり近いです。 "、しかしそれは' acQuery.Include(インクルード) 'で壊れます'エラーは '暗黙のうちに 'Microsoft.Data.Entity.Query.IIncludableQueryable 'をMicrosoft.Dataに変換できません。 Entity.Query.IIncludableQueryable ''はいくつかの "回避策"を試みましたが、役に立たなかった。 –

+0

GeneralMetadataを削除すると、「型を暗黙的に変換できません。」Microsoft.Data.Entity.Query.IIncludableQueryable 'から' Microsoft.Data.Entity.DbSet '' –

+0

@ThomasAndreèLian私自身のdbで試してみましたが、うまくいきました。あなたは' System.Data.Entity'を参照していますか?また、最初のインクルードなし(foreachではなく)のエラーが出ますが、 'var acQuery = ctx.ArticleContents.Select(a => a); 'を実行することで解決できます。 –

1

私はアレキサンダーDerckのソリューションに似たものを使用しています。 (コメントに記載されている例外については、ctx.ArticleContents.AsQueryable()も有効です。)

私はBaseAdminControllerを使用しているいくつかのCRUD MVCサイトについては、導かれた具体的なコントローラでは、Includesを動的に追加できます。 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; 
} 

indexアクション:私が使用したコンクリートコントローラーで

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)); 
関連する問題