Nhibernate return a specific type of union subclass in a QueryOver with join

喜欢而已 提交于 2019-12-13 04:27:40

问题


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

which returns this sql query

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)]

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

Here is my entities

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
{


}

回答1:


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


来源:https://stackoverflow.com/questions/11491592/nhibernate-return-a-specific-type-of-union-subclass-in-a-queryover-with-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!