我经常听到同事的“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调试器进行了调试,我注意到有多个产品和产品的订单有多个单位。
感谢任何帮助/参考资料。
由于
答案 0 :(得分:0)
与其他查询类型(HQL,Criteria,QueryOver)相比,NHibernate会自动丢弃Linq查询中的重复根实体。但正如您在上一条评论中所说,您仍然从数据库中获取了很多行,因此您的查询可能会很慢。
答案 1 :(得分:0)
使用像HibernatingRhinos这样的东西会对你有很大的帮助。我已经使用了他们的EF工具,并避免了笛卡尔产品的许多问题,我不知道其他情况。 ORM创建笛卡尔积的主要原因通常是对对象树的加载/深度读取。使用基于视图的模型对象可以轻松避免它,而不是通过在代码中将对象链接在一起来尝试构建结果集。