0

DDD の誇大宣伝に触発されて、データベースがまったくないふりをしてクラスを設計しました。次に、NHibernate を使用して、クラスをデータベース テーブルにマップしました。クラス グラフの一部は次のようになります。注文 (hasmany)--> 製品 (belongsto)--> 販売者 特定の販売者に発注されたすべての注文を取得します。私はコードを持っています:

public class Order:ActiveRecordBase<Order>
{
    [HasMany]
    public ICollection<Product> Items{get;set;}
    ...
}

public class Product: Order:ActiveRecordBase<Product>
{
    [BelongsTo]
    public Seller Seller{get; set;} 
    ...
}

public class OrderRepository:IOrderRepository
{
    public IQuerable<Order> GetOrdersBySellerId(int sellerId)
    {
        return Order.FindAll().AsQuerable.Where(x=>x.Items.Count > 0 &&
                                                   x.Items.First().Seller.SellerID == sellerId).AsQuerable();

    }
}

きれいではありませんが、単体テストでは機能しました。実際のデータをデータベースに注入し始めるまで、私は幸せでした。吐きたいほどの出来の悪さ。そこで、リポジトリ コードについて少し調査を行いました。当然のことながら、必要な注文を見つけるには、Order テーブルからすべてのデータを取得し、Product テーブルからすべてのデータを取得し、Seller テーブルから一部のデータを取得する必要がありました。

だから、ここに私の問題があります。データベース領域の完全なダミーとして、リポジトリ コードがひどく臭いことはわかっていても、リポジトリ コードを改善する方法がわかりません。そのため、Order クラスを変更して Seller クラスへの参照を持たせ、hql を使用して Where 句を追加し、パフォーマンスを向上させたいと考えています。しかし、データベースの問題によるクラス構造の変更は、DDD の原則に違反しているようです。

特に私のリポジトリコードを改善する上で、あなたの提案は何ですか? ActiveRecord と hql に Linq を試しました。しかし、それらを機能させることができませんでした。

4

2 に答える 2

0

多くの調査の後、私はこのhqlステートメントを得ました

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
     string hql = @"select  o 
                    from     Order o, Product p
                    where    p.Seller.SellerID=:sellerID
                    and      p in elements(o.Items )";

     SimpleQuery<Order> q = new SimpleQuery<Order>(hql);
     q.SetParameter("sellerID", sellerID);
            return q.Execute().AsQueryable();
}

この投稿をありがとう。Ayende の返信からアイデアを得ました。これでパフォーマンスが上がるかどうか教えてください。

于 2009-11-18T12:44:55.283 に答える
0

AFAIK ActiveRecord は LINQ を直接サポートしていませんが、LINQ to NHibernate プロバイダーを使用できます。これがサンプルです。最後に、より伝統的で成熟した基準 API を使用する例があります。

更新:申し訳ありませんが、私は間違っていました。からエンティティを継承し、そのプロパティActiveRecordLinqBase<T>を使用してクエリを作成する必要があるようです。Queryable

次のように見えるはずです

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
    return Order.Queryable
               .Where(x=>x.Items.Count > 0 && x.Items.First().Seller.SellerID == sellerId)();
}

プレーンに固執したい場合ActiveRecordBase<T>は、静的メソッドを使用できますActiveRecordLinq.AsQueryable<T>()

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
    return ActiveRecordLinq.AsQueryable<Order>()
               .Where(x=>x.Items.Count > 0 && x.Items.First().Seller.SellerID == sellerId)();
}

検索条件で試してみましたか?(私はこれを尋ねます。知る限り、すべてのLINQコンストラクトがNHibernateで機能するわけではないためです)

于 2009-11-18T09:39:31.560 に答える