C# nHibernate-多对多查询

C# nHibernate-多对多查询,c#,nhibernate,C#,Nhibernate,查询具有多对多关系的对象时遇到问题 我的模型看起来像这样。因此,m-n-关系是针对其自身解决的 ProductionOrder Product ProductPart +-----+ +-----+ +-----+ | | | | 1------------n | | | | n --------- 1

查询具有多对多关系的对象时遇到问题

我的模型看起来像这样。因此,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();
}
并抛出一个异常

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

Edit1-添加了c#模型类和映射

var result = Session.QueryOver<ProductionOrder>()
            .Inner.JoinQueryOver<ProductPart>(x => x.Product.Parts)
            .Where(pp => pp.PartProduct.Id == product.Id).List<ProductionOrder>();
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      
}
公共类产品
{
//更多属性
公共虚拟IList部分{get;set;}
}
公共类产品部分:IHaveId
{
///母公司
公共虚拟产品包含产品{get;set;}
///孩子
公共虚拟产品PartProduct{get;set;}
//更多属性
}
映射

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);
    }
}
公共类ProductMap:ClassMap
{
公共产品地图()
{
Id(x=>x.Id);
HasMany(x=>x.Parts).KeyColumn(“ContainingProductId”).Inverse().Cascade.DeleteOrphan().BatchSize(20);
}
}
公共类ProductPartMap:ClassMap
{
公共产品零件图()
{
Id(x=>x.Id);
参考文献(x=>x.ContainingProduct);
参考文献(x=>x.PartProduct);
}
}
查询应为:

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();
var result=Session.QueryOver()
.Inner.JoinQueryOver(x=>x.Product)
.internal.JoinQueryOver(x=>x.Parts)
.Where(x=>x.PartProduct.Id==product.Id)
.List();
请注意,在NHibernate中,“自然连接条件”(主键/外键)由
JoinQueryOver
隐式给出,因此您不必重复它们。

查询应为:

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();
var result=Session.QueryOver()
.Inner.JoinQueryOver(x=>x.Product)
.internal.JoinQueryOver(x=>x.Parts)
.Where(x=>x.PartProduct.Id==product.Id)
.List();

请注意,在NHibernate中,“自然连接条件”(主键/外键)由
JoinQueryOver
隐式给出,因此您不必重复它们。

如果您向我们展示C#实体会更容易。。。还不清楚ProductPart关系是如何建立的。@xanatos添加了模型和映射,我希望现在关系清楚了。如果您向我们展示C#实体,会更容易。。。不清楚ProductPart关系是如何建立的。@xanatos添加了模型和映射,我希望现在关系清楚了。在我的例子中,它必须是
Where(x=>x.PartProduct.Id==product.Id)
。其余的都很好用。非常感谢你!在我的例子中,它必须是
其中(x=>x.PartProduct.Id==product.Id)
。其余的都很好用。非常感谢你!