0

受DDD炒作的启发,我设计了我的课程,假装没有数据库。然后使用NHibernate将这些类映射到数据库表。部分类图形如下所示:Order(hasmany) - > Product(belongssto) - > 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表中获取所有数据,并从Product表中获取所有数据,并从Seller表中获取一些数据。

所以,我的问题来了。作为数据库领域的一个虚拟角色,我不知道如何改进我的存储库代码,即使我知道它很糟糕。所以,我很想修改我的Order类以引用Seller类,以便我可以使用hql来添加Where子句来提高性能。但是由于数据库问题而修改类结构似乎违反了DDD原则。

您的建议是什么,特别是在改进我的存储库代码?我曾尝试Linq的ActiveRecord和hql。但无法让他们工作。

回答

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(); 
} 

感谢this岗位。我从Ayende的回复中得到了这个想法。请让我知道这是否会启动性能。

0

虽然AFAIK ActiveRecord没有直接支持LINQ,但可以使用LINQ to 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)(); 
} 

您试过了吗? (我问这个,因为据我所知,你不能所有的LINQ构建NHibernate的工作)

+0

ActiveRecord确实支持Linq。我从它的源代码中发现了它:)。但我无法在ActiveRecord的测试中找到像我一样复杂的代码:( – 2009-11-18 09:43:39

+0

的确如此,我已更正了我的文章,对于desinformation的对不起。 – 2009-11-18 10:09:31

+0

谢谢。我的代码片段完全一样(从ActiveRecordLinqBase继承)但是我得到了一个异常,我怀疑是发生在Items.First()上,因为First是一个扩展方法,ActiveRecord Linq没有库来理解它。 – 2009-11-18 10:59:04