1

私は EF でリポジトリ パターンを使用しています。私はそれでかなり満足していると思いますが、1 つの疑問が残ります。

エンティティを熱心に読み込みたい場合、これを行う最善の方法は何ですか?

たとえば、エンティティにマッピングされたリポジトリがあります。

public class EFFooRepository : IFooRepository
{
     public IQueryable<Foo> GetFoo()
     {
        .....
     }
}

Foo オブジェクトと Bar オブジェクトを取得したい場合

db.Foo.Include("Bar")

しかし、私のリポジトリは Foo しか返さないので、別のメソッド GetFooAndBar を作成する必要がありますか?

より良い方法はありますか?

4

2 に答える 2

1

私も同じことを経験しました。リポジトリ パターンを実装するとき、DbSet< T > を公開せずに、DbSet< T > が実装する IQueryable< T > および IEnumerable< T > を使用できるようにしたいと考えていました (古き良き情報隠蔽)。

したがって、すべての IQueryable / IEnumerable 関数が、リポジトリ内の DbSet< T > の対応する関数を呼び出せるようにするだけで十分だと考えました。

今日まで、私のすべての IQueryable< T > 関数にはこれで十分でした。今日、 IQueryable.Include を除いて、あなたが説明したのと同じ問題があることを発見しました。コンパイラ エラーはありませんが、データは読み込まれません。

広範な結果の後、その理由は MSDN のQueryableExtensions.Include Method (IQueryable, String)の説明に記載されていることがわかりました

この拡張メソッドは、ソース IQueryable オブジェクトの Include(String) メソッドが存在する場合、そのメソッドを呼び出します。ソース IQueryable に一致するメソッドがない場合、このメソッドは何もしません。

したがって、対応する DbSet リポジトリを呼び出す一致する include ステートメントをリポジトリに記述するだけで済みました。IQueryable / IEnumerable 関数は、DbSet の対応する関数を呼び出すだけです。

public class Repository<T> : 
    System.Linq.IQueryable<T>, System.Collections.Generic.IEnumerable<T>,
    System.Linq.IQueryable, System.Collections.IEnumerable
    where T : class, new()
{
    public Repository(DbContext dbContext)
    {
        this.dbContext = dbContext;
        this.dbSet = dbContext.Set<T>();
    }

    public readonly DbSet<T> dbSet;
    private readonly DbContext dbContext;

    public virtual DbQuery<T> Include(string path)
    {
        return this.dbSet.Include(path);
    }

    // other Repository functions: Find / Add / Update / Remove etc

完全を期すために、IQueryable / IEnumerable の実装:

    #region IQueryable
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return ((IQueryable<T>)this.dbSet).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)this.dbSet).GetEnumerator();
    }

    Type IQueryable.ElementType
    {
        get { return ((IQueryable<T>)this.dbSet).ElementType; }
    }

    System.Linq.Expressions.Expression IQueryable.Expression
    {
        get { return ((IQueryable)this.dbSet).Expression; }
    }

    IQueryProvider IQueryable.Provider
    {
        get { return ((IQueryable)this.dbSet).Provider; }
    }
    #endregion IQueryable

現在、次のように動作し、アドレスが含まれています。

using (MyDbContext dbContext = new MyDbContext(...))
{
    Repository<Customer> customers = new Repository<Customer>(dbContext);
    var happyCustomers = customers
        .Include(customer => customer.Address)
        .Where(customer => customer.IsHappy);
    Show(happyCustomers);
}
于 2016-03-09T16:02:58.367 に答える
0

Bar遅延読み込みを有効にしている場合は、後で (プロパティにアクセスするとき) を読み込むことができます。ただし、同時にデータをロードするメソッドを作成する場合は、特定のリポジトリ メソッドを作成する必要がありFooます。Bar

于 2012-05-10T09:07:20.333 に答える