0

这是我当前的 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>();

返回此 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)]

基本上这里发生的事情是我加入了一个 unionsubclass 并且在查询中它包括 Item 类型的所有子类。

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

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

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
{


}
4

1 回答 1

2

如果 TMapItem 是特定类型 NH 将只查询 TMapItem 的表。但是,正如您在加入类型时在评论中所说的那样未知,因此所有表都已合并。为避免这种情况,您必须在包含该类型的外键旁边引入一列。我不确定,但 NH 应该优化查询。

// mapping using FluentNhibernate
ReferencesAny(x => x.Property)
    .KeyType()
    .MetaValue<Subclass1>("foo")
    .MetaValue<Subclass2>("bar");
于 2012-07-15T16:39:56.600 回答