0

DDD 과대 광고에서 영감을 얻어 필자는 클래스가 전혀 데이터베이스가없는 것처럼 디자인했습니다. 그리고 나서 NHibernate를 사용하여 클래스들을 데이터베이스 테이블에 매핑했다. 내 클래스 그래프의 일부는 Order (hasmany) -> Product (belongsto) -> Seller와 같습니다. 특정 판매자에 대한 모든 주문을 검색합니다. 나는 코드를 가지고있다 :Nhibernate 및 Activerecord를 사용한 데이터베이스 성능

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 테이블의 All 데이터와 Product 테이블의 All 데이터와 Seller 테이블의 일부 데이터를 가져와야했습니다.

여기 내 문제가 있습니다. 데이터베이스 영역의 총 모조품으로서 저장소 코드를 악독하게 생각하더라도 저장소 코드를 향상시키는 방법을 모르겠습니다. 따라서 판매자 클래스에 대한 참조를 갖도록 Order 클래스를 수정하여 hql을 사용하여 성능 향상을 위해 Where 절을 추가 할 수 있습니다. 그러나 데이터베이스 문제로 인해 클래스 구조를 수정하는 것은 DDD 원칙을 위반하는 것으로 보입니다.

제안 사항은 무엇입니까? 특히 저장소 코드를 개선 할 때 어떤 점이 좋습니까? Linq 액티브 레코드 및 hql 시도했다. 그러나 그들을 일하게 할 수는 없었습니다.

답변

0

을 (AFAIK 당신이 모든 LINQ는 NHibernate에 대한 작업을 구성하기 때문에 나는이에게) 나는이 HQL 문을 this 게시물에 대한

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의 대답에서 아이디어를 얻었다. 성능이 부팅되는지 알려주세요.

0

AFAIK ActiveRecord는 LINQ를 직접 지원하지 않지만 LINQ를 NHibernate 공급자에 사용할 수 있습니다. Here은 샘플입니다. 결국 더 전통적이고 성숙한 기준 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)(); 
} 

검색 기준을 사용해 보셨습니까? 많은 연구 후

+0

ActiveRecord는 Linq를 지원합니다. 나는 그것의 소스 코드에서 그것을 발견했다 :). 하지만 ActiveRecord의 테스트에서 복잡한 코드를 찾을 수 없었습니다. ( –

+0

실제로 게시물을 수정했습니다. 죄송합니다. –

+0

감사합니다. ActiveRecordLinqBase에서 상속받은 코드 조각과 정확히 동일합니다. 하지만 먼저 예외 (확장) 메서드 및 ActiveRecord Linq 그것을 이해하는 라이브러리가 없기 때문에 Items.First (에서 발생하는 것으로 의심되는 예외가 있어요. –