Nhibernate在带有join的查询版本中返回特定类型的union子类

Nhibernate在带有join的查询版本中返回特定类型的union子类,nhibernate,inheritance,join,queryover,Nhibernate,Inheritance,Join,Queryover,这是我当前的nhibenate查询 MappedHSPItemDto itemDtoAlias = null; TItem itemAlias = default(TItem); return Session.QueryOver<TMapItem>() .JoinAlias(x => x.Item, () => itemAlias, Joi

这是我当前的nhibenate查询

        MappedHSPItemDto itemDtoAlias = null;
        TItem            itemAlias    = default(TItem);

        return
            Session.QueryOver<TMapItem>()
                .JoinAlias(x => x.Item, () => itemAlias, JoinType.InnerJoin)
                .Where(x => x.HealthServiceProvider == hsp)
                .SelectList(list => list
                                        .Select(x => x.Id).WithAlias(() => itemDtoAlias.Id)
                                        .Select(x => x.Version).WithAlias(() => itemDtoAlias.Version)
                                        .Select(x => x.HSPItemCode).WithAlias(() => itemDtoAlias.HSPItemCode)
                                        .Select(x => x.HSPItemName).WithAlias(() => itemDtoAlias.HSPItemName)
                                        .Select(x => itemAlias.Code).WithAlias(() => itemDtoAlias.CirrusItemCode)
                                        .Select(x => itemAlias.Name).WithAlias(() => itemDtoAlias.CirrusItemName)
                )
                .TransformUsing(Transformers.AliasToBean<MappedHSPItemDto>()).List<MappedHSPItemDto>();
基本上,这里发生的是im加入一个unionsubclass,并在查询中包含Item类型的所有子类

有没有办法只在查询中包含特定类型的子类

im使用代码映射,下面是其中一个子类的映射

public class MedicineMap : UnionSubclassMapping<Medicine>
{
    public MedicineMap()
    {
        Property(p => p.Code, Rules.CodeRule);
        Property(p => p.Name, Rules.StrLength255AndNotNull);
        Property(p => p.GenericName, Rules.StrLength400AndNullable);

        Bag(x => x.HMOMedicineMappings, bag =>
        {
            bag.Inverse(true); 
            bag.Key(k => k.Column(col => col.Name("ItemId"))); 

        }, a => a.OneToMany());

        Bag(x => x.HSPMedicineMappings, bag =>
        {
            bag.Inverse(true); 
            bag.Key(k => k.Column(col => col.Name("ItemId"))); 


        }, a => a.OneToMany());
    }
}
公共类MedicineMap:UnionSubclass映射
{
公共医疗
{
属性(p=>p.Code,Rules.CodeRule);
属性(p=>p.Name,Rules.StrLength255AndNotNull);
属性(p=>p.GenericName,Rules.strlength400和nullable);
Bag(x=>x.hmomedicine映射,Bag=>
{
反方向(真);
bag.Key(k=>k.Column(col=>col.Name(“ItemId”));
},a=>a.OneToMany());
袋子(x=>x.HSPMedicineMappings,袋子=>
{
反方向(真);
bag.Key(k=>k.Column(col=>col.Name(“ItemId”));
},a=>a.OneToMany());
}
}
这是我的实体

public abstract class Item : EntityBase
{
    public virtual string Code { get; set; }
    public virtual string Name { get; set; }

}

public class Medicine : Item
{
    public Medicine()
    {
        HSPMedicineMappings = new List<HSPMedicineMapping>();
        HMOMedicineMappings = new List<HMOMedicineMapping>();
    }
    public virtual string GenericName { get; set; }
    public virtual IList<HSPMedicineMapping> HSPMedicineMappings { get; set; }
    public virtual IList<HMOMedicineMapping> HMOMedicineMappings { get; set; }

}


public class AssetEquipment : Item
{
    public AssetEquipment()
    {
        HSPAssetEquipmentMappings = new List<HSPAssetEquipmentMapping>();
        HMOAssetEquipmentMappings = new List<HMOAssetEquipmentMapping>();
    }
    public virtual IList<HSPAssetEquipmentMapping> HSPAssetEquipmentMappings { get; set; }
    public virtual IList<HMOAssetEquipmentMapping> HMOAssetEquipmentMappings { get; set; }
}

public abstract class HSPItemMapping : EntityBase
{
    public virtual HealthServiceProvider HealthServiceProvider { get; set; }
    public virtual string HSPItemCode { get; set; }
    public virtual string HSPItemName { get; set; }
    public virtual Item Item { get; set; }


}

public class HSPMedicineMapping : HSPItemMapping
{


}
公共抽象类项:EntityBase
{
公共虚拟字符串代码{get;set;}
公共虚拟字符串名称{get;set;}
}
公营医疗:项目
{
公共医学()
{
HSPMedicineMappings=新列表();
HMOMedicineMappings=新列表();
}
公共虚拟字符串GenericName{get;set;}
公共虚拟IList映射{get;set;}
公共虚拟IList HMOMedicineMappings{get;set;}
}
公共类资产设备:项目
{
公共资产设备()
{
HSPAssetEquipmentMappings=新列表();
HMOAssetEquipmentMappings=新列表();
}
公共虚拟IList HSPAssetEquipmentMappings{get;set;}
公共虚拟IList HMOAssetEquipmentMappings{get;set;}
}
公共抽象类HSPItemMapping:EntityBase
{
公共虚拟HealthServiceProvider HealthServiceProvider{get;set;}
公共虚拟字符串HSPItemCode{get;set;}
公共虚拟字符串HSPItemName{get;set;}
公共虚拟项项{get;set;}
}
公共类HSPMedicineMapping:HSPItemMapping
{
}

如果TMapItem是特定类型,NH将只查询TMapItem表。但是,正如您在注释中所说,当加入类型时是未知的,因此所有表都是联合的。为了避免这种情况,必须在保存类型的foreignkey旁边引入一列。我不确定,但是NH应该优化查询

// mapping using FluentNhibernate
ReferencesAny(x => x.Property)
    .KeyType()
    .MetaValue<Subclass1>("foo")
    .MetaValue<Subclass2>("bar");
//使用FluentNhibernate进行映射
引用任意(x=>x.Property)
.KeyType()
.MetaValue(“foo”)
.元价值(“bar”);

如果TMapItem是特定类型,NH将只查询TMapItemYep表中的TMapItem,但问题是TMapItem与子表(即x)连接的部分。Item,Item是一个抽象基类。它有几个子类,所以每当我加入它时,它都会为所有子类生成一个union all查询。好的,我知道了,但是我使用代码映射,在代码映射中可能吗?我无法使用UNIONSUBSCRASE映射,它没有鉴别器,所以上面的解决方案不起作用,它也不会有外键关系,我更新了我的帖子以获取更多详细信息。请您说明如何使用过滤器查询
x.Property
,比如说
x.Property.Id==someId
?@Christian看起来不是这样easy@Firo我同意你的看法。这就是为什么我仍然不确定将
Any
vs
HasOne
HasMany
结合使用的原因。任何地方,谢谢你的尝试!:)
// mapping using FluentNhibernate
ReferencesAny(x => x.Property)
    .KeyType()
    .MetaValue<Subclass1>("foo")
    .MetaValue<Subclass2>("bar");