2014-01-15 5 views
5

私は、このリポジトリを持ってEF eager loadingが期待どおりに機能しないのはなぜですか?

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class 
{ 
    private readonly DbContext context; 
    private readonly DbSet<TEntity> dbEntitySet; 

    public Repository(DbContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException("context"); 

     this.context = context; 
     this.dbEntitySet = context.Set<TEntity>(); 
    } 

    public IEnumerable<TEntity> GetAll() 
    { 
     return this.dbEntitySet; 
    } 

    public IEnumerable<TEntity> GetAll(string include) 
    { 
     return this.dbEntitySet.Include(include); 
    } 

    public IEnumerable<TEntity> GetAll(string[] includes) 
    { 
     foreach (var include in includes) 
      this.dbEntitySet.Include(include); 

     return this.dbEntitySet; 
    } 

    public void Create(TEntity model) 
    { 
     this.dbEntitySet.Add(model); 
    } 

    public void Update(TEntity model) 
    { 
     this.context.Entry<TEntity>(model).State = EntityState.Modified; 
    } 

    public void Remove(TEntity model) 
    { 
     this.context.Entry<TEntity>(model).State = EntityState.Deleted; 
    } 

    public void Dispose() 
    { 
     this.context.Dispose(); 
    } 
} 

と私が持っている問題は、この方法である:

public IEnumerable<TEntity> GetAll(string[] includes) 
{ 
    foreach (var include in includes) 
     this.dbEntitySet.Include(include); 

    return this.dbEntitySet; 
} 

私はそれを実行し、リターンの前にブレークポイントを置くとき、それはforeachのかのようですは無視されています。

それ以上の方法では正常に動作します:私は変更する場合D:

含まないない結果を引き戻すが、
var a = this.Repository.GetAll(new string[] { "ForbiddenUsers", "ForbiddenGroups" }).ToList(); 

が含まれています:

public IEnumerable<TEntity> GetAll(string include) 
{ 
    return this.dbEntitySet.Include(include); 
} 

はそれを呼び出すために、私は基本的にこれを行います

var a = this.Repository.GetAll("ForbiddenUsers").ToList(); 

これは問題なく動作します。

誰かに解決策を教えてもらえますか?

+0

+1のため:私はこのようなラムダ式を使用します、あなたの代わりに

public IEnumerable<TEntity> GetAll(string[] includes) { IQueryable<T> query = this.dbEntitySet; foreach (var include in includes) query = query.Include(include); return query; } 

public IEnumerable<TEntity> GetAll(string[] includes) { foreach (var include in includes) this.dbEntitySet.Include(include); return this.dbEntitySet; } 

正しいコードは以下の通りですGetAllメソッドのアイデア!有用! – statue

答えて

7
はこのように見て、あなたの方法を変更し

public IEnumerable<TEntity> GetAll(string[] includes) 
{ 
    var query = this.dbEntitySet; 

    foreach (var include in includes) 
     query = query.Include(include); 

    return query; 
} 

Include方法はDbSetを変異させていない、それだけであなた含めると、あなたに新しいDbQueryを返します。

+0

私はこれらを試してみましょう – r3plica

+0

最初のものについては、無効なキャスト例外が発生します.2番目の例外は、実行するとエラーになります(うまくコンパイルされます)。私は問題が何かを確認するためにいくつかのテストを行うつもりです – r3plica

+0

ええ、2番目の方法の問題は、インクルードが、ちょうどうまく動作しないすべての結合された文字列でナビゲーションプロパティを作成しようとしていると思います。 – r3plica

1

このコードは正しくありません。

public IEnumerable<TEntity> GetAll(Expression<Func<T, object>>[] includes) 
{ 
    IQueryable<T> query = this.dbEntitySet; 

    foreach (var include in includes) 
     query = query.Include(include); 

    return query; 
} 
+0

ここではLambdasは動作しません。 'Expression >'は 'Expression >'に変換できません。ラムダのキャストは魔法を捨てると信じています。 –

+0

@CoryNelson私は決して表現>に言及しませんでした。 Expression >は私にとってはうまく機能します。あなたは私のコードでTRetをどこで見ましたか? – CodeNotFound

+0

実際、あなたはそれを言及していませんでした - 私が指摘していることは、みんなのlambdas *は 'object'ではなく、いくつかの型になるということです - あなたのメソッドの有用性が' Func 'などは' Func 'の式に変換できません。 –

関連する問題