究竟什么是NHibernate中的笛卡尔积?

时间:2013-05-15 18:38:35

标签: nhibernate fluent-nhibernate

我经常听到同事的​​“Cartesian Product”这个词,当时有一个领域模型,其中包含一个集合中的集合并且渴望获取相同的集合。假设我有以下模型。

public class Order{
  List<Product> Products
}
public class Product{
  List<Units> Units
}

现在他们说,如果我尝试用产品和单位获取订单,我应该得到一个笛卡尔积(又名重复...)。 但是,当我通过启用ShowSql测试它时,我似乎没有得到任何重复。 这是我的存储库类

    public List<Order> GetOrdersWithProductsAndUnits()
    {
        return GetSession().Query<Order>()
                           .FetchMany(order => order.Products)
                           .ThenFetch(product => product.Units)
                           .ToList();
    } 

这是启用ShowSql时的sql输出。这看起来很好,正如预期的那样加入必要的表格。

select order0_.Id as Id8_0_, 
childstock1_.Id as Id23_1_,
childstock2_.Id as Id24_2_, 
order0_.CustomerName as Customer2_8_0_,  
order0_.City as City8_0_,
childstock1_.Size as Size23_1_,
childstock2_.Box as Box24_2_,
from Orders order0_  
left outer join Products childstock1_ on order0_.Id=childstock1_.OrderId  
left outer join Units childstock2_ on childstock1_.Id=childstock2_.ProductId

我的数据库中有125个订单,当我急切地用产品和单位获取订单时,我仍然会得到125条记录。

List<Order> orders = repository.GetOrdersWithProductsAndUnits();
   Assert.That(orders.Count,Is.EqualTo(125));

此外,当我通过Visual Studio调试器进行检查时,我在产品或单元级别的订单集合中找不到任何重复项。

我期待我的数据库中的单位订单数量接近1000(接近1000)因为笛卡尔产品导致重复。我错过了一些微不足道的事情,我对笛卡尔积的理解是否有偏差?或者我正在使用的查询API是否会自动解决笛卡尔积问题。

仅供参考:我也确定数据设置。我通过Visual Studio调试器进行了调试,我注意到有多个产品和产品的订单有多个单位。

感谢任何帮助/参考资料。

由于

2 个答案:

答案 0 :(得分:0)

与其他查询类型(HQL,Criteria,QueryOver)相比,NHibernate会自动丢弃Linq查询中的重复根实体。但正如您在上一条评论中所说,您仍然从数据库中获取了很多行,因此您的查询可能会很慢。

答案 1 :(得分:0)

使用像HibernatingRhinos这样的东西会对你有很大的帮助。我已经使用了他们的EF工具,并避免了笛卡尔产品的许多问题,我不知道其他情况。 ORM创建笛卡尔积的主要原因通常是对对象树的加载/深度读取。使用基于视图的模型对象可以轻松避免它,而不是通过在代码中将对象链接在一起来尝试构建结果集。