问题
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