我无法查询具有多对多关系的对象。
我的模特看起来像这样。因此,m-n关系将自行解决。
ProductionOrder Product ProductPart
+-----+ +-----+ +-----+
| | | | 1------------n | |
| | n --------- 1 | | | |
| | | | n------------1 | |
+-----+ +-----+ +-----+
一种产品可以是许多产品的一部分,一种产品可以有许多部件
我现在尝试检索给定产品属于的ProductionOrder
要生产的产品。
在简单的SQL中,这非常简单并且工作正常
SELECT * FROM ProductionOrder po
INNER JOIN Product p
ON po.ProductId = p.Id
INNER JOIN ProductPart pp
ON p.Id = pp.ContainingProductId
WHERE pp.PartProductId = 403
但是我没能在nHibernate中做到这一点。
首先尝试:
我尝试按照查询返回任何内容:
private decimal GetNeededForProduction(Product product)
{
//Retrieve all ProductionOrders where Product is a Part
var productionOrders = Session.Query<ProductionOrder>()
.Where(x => x.Product.Parts.Select(p => p.PartProduct.Id).Contains(product.Id))
.Fetch(x => x.Product).ThenFetch(x => x.Parts)
.ToList();
}
第二次尝试:
我还发现WhereRestriction有一个方法IsIn
,但恰恰相反。
var test = Session.QueryOver<ProductionOrder>()
.WhereRestrictionOn(x => x.Product.Parts.Select(p => p.PartProduct.Id)).IsIn(new long[] {product.Id});
并且还会抛出异常
InvalidOperationException was unhandled by user code
variable 'x' of type 'Pmc.Model.Production.ProductionOrder' referenced from scope '', but it is not defined
第三次尝试:
var result = Session.QueryOver<ProductionOrder>()
.Inner.JoinQueryOver<ProductPart>(x => x.Product.Parts)
.Where(pp => pp.PartProduct.Id == product.Id).List<ProductionOrder>();
抛出
{"The multi-part identifier \"productpar1_.PartProductId\" could not be bound."}
提前致谢
Edit1 - 添加了c#-model-classes和映射
public class Product
{
//More properties
public virtual IList<ProductPart> Parts { get; set; }
}
public class ProductPart : IHaveId
{
/// <summary> parent </summary>
public virtual Product ContainingProduct { get; set; }
/// <summary> child </summary>
public virtual Product PartProduct { get; set; }
//More properties
}
映射
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Id(x => x.Id);
HasMany(x => x.Parts).KeyColumn("ContainingProductId").Inverse().Cascade.DeleteOrphan().BatchSize(20);
}
}
public class ProductPartMap : ClassMap<ProductPart>
{
public ProductPartMap()
{
Id(x => x.Id);
References(x => x.ContainingProduct);
References(x => x.PartProduct);
}
}
答案 0 :(得分:2)
查询应为:
var result = Session.QueryOver<ProductionOrder>()
.Inner.JoinQueryOver<Product>(x => x.Product)
.Inner.JoinQueryOver<ProductPart>(x => x.Parts)
.Where(x => x.PartProduct.Id == product.Id)
.List();
请注意,在NHibernate中,“自然连接条件”(主键/外键)由JoinQueryOver
隐式赋予,因此您不必重复它们。