Nhibernate在带有联接的QueryOver中返回特定类型的联合子类 [英] Nhibernate return a specific type of union subclass in a QueryOver with join

查看:97
本文介绍了Nhibernate在带有联接的QueryOver中返回特定类型的联合子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我当前的邻苯甲酸酯查询

This is my current nhibenate query

        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>();

返回此sql查询

SELECT
        this_.Id as y0_,
        this_.Version as y1_,
        this_.HSPItemCode as y2_,
        this_.HSPItemName as y3_,
        itemalias1_.Code as y4_,
        itemalias1_.Name as y5_      
    FROM
        HSPMedicineMapping this_      
    inner join
        (
            select
                Id,
                Version,
                Code,
                Name,
                GenericName,
                1 as clazz_              
            from
                Medicine              
            union
            all select
                Id,
                Version,
                Code,
                Name,
                null as GenericName,
                2 as clazz_              
            from
                AssetEquipment              
            union
            all select
                Id,
                Version,
                Code,
                Name,
                null as GenericName,
                3 as clazz_              
            from
                [Procedure]              
            union
            all select
                Id,
                Version,
                Code,
                Name,
                null as GenericName,
                4 as clazz_              
            from
                Supply              
            union
            all select
                Id,
                Version,
                Code,
                Name,
                null as GenericName,
                5 as clazz_              
            from
                Examination              
            union
            all select
                Id,
                Version,
                Code,
                Name,
                null as GenericName,
                6 as clazz_              
            from
                OtherItem          
        ) itemalias1_              
            on this_.ItemId=itemalias1_.Id      
    WHERE
        this_.HealthServiceProviderId = @p0;

@p0 = 12 [Type: Int64 (0)]

基本上,这里发生的事情是我加入了union子类,并在查询中加入了Item类型的所有子类.

basically what is happening here is im joining to a unionsubclass and on the query its including all subclass of the Item type.

有没有一种方法可以只在查询中包括特定类型的子类?

Is there a way to just include the specific type of subclass in a query?

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

im using mapping by code, below is the mapping for one of the subclass

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

这是我的实体

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
{


}

推荐答案

如果TMapItem是特定类型,NH将仅查询TMapItem的表.但是,正如您在注释中所说的那样,在加入Type时是未知的,因此所有表都被合并.为避免这种情况,您必须在保存该类型的外键旁边插入一列.我不确定,但是NH应该优化查询.

if TMapItem is the specific type NH will only query the table of TMapItem. However as you said in comment when joining the Type is unknown hence all tables are unioned. To avoid this you have to introduce a column next to the foreignkey holding the type. Im not sure but NH should optimise the query then.

// mapping using FluentNhibernate
ReferencesAny(x => x.Property)
    .KeyType()
    .MetaValue<Subclass1>("foo")
    .MetaValue<Subclass2>("bar");

这篇关于Nhibernate在带有联接的QueryOver中返回特定类型的联合子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆