在NHibernate中,我正在使用Table-per-Class Hierarchy Inheritance映射。我的表看起来像这样:
Items表具有继承映射,有3个C#类(实体),它们是'UserProfiles','Destinations'和'Groups',ItemType列是鉴别器。 ItemMembers表将Items表链接回自身(通过多对多),以便用户可以属于多个目标或组,而目标/组可以有许多用户等。
我使用类似的方式映射它:
public class ItemMap : ClassMapping<Item>
{
public ItemMap()
{
Table("Items");
Id(...snip...
Discriminator(x => { x.Column("ItemType"); x.Force(true); });
...other props (snip)...
和,其中一个实体:
public class UserProfileMap : SubclassMapping<UserProfile>
{
public UserProfileMap()
{
DiscriminatorValue("UserProfile");
.... other props (snip)...
目标和组的映射类似,它们的所有类都扩展了Item类:
public class UserProfile : Item { }
public class Destination : Item { }
public class Group : Item { }
到目前为止,这似乎很有效。我的问题是我想将UserProfiles链接到Destinations,反之亦然。所以我创建了一个UserDestination实体并映射它:
public class UserDestination
{
public virtual UserProfile Profile { get; set; }
public virtual Destination Destination { get; set; }
}
public class UserDestinationMap : ClassMapping<UserDestination>
{
public UserDestinationMap()
{
Table("ItemMembers");
Id(... snip...
ManyToOne(x => x.Profile, x =>
{
x.Column("ChildItemId");
x.NotNullable(true);
});
ManyToOne(x => x.Destination, x =>
{
x.Column("ParentItemId");
x.NotNullable(true);
});
}
}
public class UserProfile : Item
{
.... other props (snip)....
public virtual ISet<UserDestination> FollowedDestinations { get; set; }
}
...麻烦的是,每当我尝试为用户检索目标时,我也会得到组(因为同一个表用于多对多链接),我收到以下错误:
var usersDestinations = userProfile.FollowedDestinations
.Select(fd => fd.Destination)
.ToList();
Unable to cast object of type 'MyApp.Group' to type 'MyApp.Destination'.
我可以通过在UserProfile实体上映射UserDestinations集合时包含WHERE子句来解决这个问题:
Set(x => x.FollowedDestinations, x =>
{
x.Inverse(true);
x.Cascade(Cascade.All | Cascade.DeleteOrphans);
x.Lazy(CollectionLazy.Extra);
x.Key(k => { k.Column("ChildItemId"); });
x.Where("(SELECT COUNT(*) FROM Items xitems WHERE xitems.Id = ParentItemId AND xitems.ItemType = 'Destination') > 0");
}, x => x.OneToMany());
但这似乎有点像黑客,我不知道是否会有未来的潜在问题。那么有更好的方法吗?