1

私の現在のプロジェクトでは、汎用リポジトリインターフェイスを使用しています。

public interface IDataSource : IDisposable
{
    void Add<T>(T newItem) where T : EntityBase;

    T Get<T>(Guid id) where T : EntityBase;
    T Get<T>(Expression<Func<T, bool>> predicate) where T : EntityBase;
    IQueryable<T> GetAll<T>(Expression<Func<T, bool>> predicate = null) where T : EntityBase;
    int Count<T>(Expression<Func<T, bool>> predicate = null) where T : EntityBase;
    bool Any<T>(Expression<Func<T, bool>> predicate = null) where T : EntityBase;

    void Update<T>(T updated) where T : EntityBase;

    void Delete<T>(Guid id) where T : EntityBase;
    void Delete<T>(T item) where T : EntityBase;

    void Commit();
}

例として、Getメソッドは次のようになります。

public T Get<T>(Expression<Func<T, bool>> predicate) where T : EntityBase
{
    return db.Set<T>().Single(predicate);
}

ここdbで、はEntityFrameworkのを拡張する私のデータコンテキストのインスタンスDbContextです。IDisposable作業単位パターンのスコープブロックで使用したり、変更をコミットする前に最後まで待機したり、その前に問題が発生した場合に全体を破棄したりできるように、すべてが実装されています。

このインターフェイスは、ビジネスロジックをデータアクセスから完全に分離するために、より複雑なクエリを処理するためにロジックレイヤーによって使用されます。したがって、そのレイヤーへのクエリは次のようになります。

public List<Product> ItemsBoughtByCustomer(Guid customerID)
{
    using (var db = DataAccess.GetContext())
    {
        List<Purchase> purchaseHistory = db.GetAll<Purchase>(p => p.CustomerID == customerID);
        List<int> IDs = purchaseHistory.Select(p => p.ProductID);
        return db.GetAll<Product>(p => IDs.Contains(p.ID));
    }
}

(はい、それは凝縮できることを理解しています。それはアプリにありますが、たとえば、これはより明確です。)

私の問題は、オブジェクトのセットを返すことがあり、後でそれが参照するもののいくつかに到達したいと思うかもしれないということです。たとえば、製品を表示する場合、ディスプレイは次のようにします。

@foreach (Comment comment in Product.Comments)
{
    <div class="comment">
        <span>@Html.UserDisplay(comment.Author)</span>
        <span>@comment.Body</span>
    </div>
}

(HTMLの品質は無視してください。これも簡単な例です)

問題は、Entity Frameworkの遅延読み込みで、クエリからエンティティを返すときにこれらのプロパティがnullのままになると、エラーがスローされることです。今、私はそのInclude()方法を知っていますが、私のリポジトリが一般的である場合、それらを適用することは困難です。完全にオフにすることもできますが、EFは、必要のないときに膨大なリンクされたコレクションの取得を開始します。モデルの構造と監査ログへのリンクは、EFからのリンクが多いことを意味します。従う。

少しスマートな方法で遅延読み込みできる方法はありますか?特定のクエリに子オブジェクトを含めるように具体的に要求できるように、子オブジェクトも取得するようなメソッド.Single().Where()を呼び出すことができるメソッドはありますか?DbSet

4

1 に答える 1

1

インクルードパスにオプションのパラメーターを追加してから、DbSetでInclude(str)を呼び出します。Getメソッドの例:

public T Get<T>(Expression<Func<T, bool>> predicate, string includePath = null) where T : EntityBase
{
    var query = db.Set<T>();

    if( !string.IsNullorWhitespace( includePath ) )
    {
        query = query.Include( includePath );
    }

    return query.Single(predicate);
}
于 2013-03-27T15:09:26.547 に答える