我的项目中有以下实体,我想使用NHibernate属性进行映射:
public interface IContent
{
int Id { get; set; }
string Name { get; set; }
}
public interface IUser
{
int Id { get; set; }
}
[Class]
public class Book : IContent
{
[Id(...), Column(...), Generator(...)]
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
[Class]
public class Collection : IContent
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
[Class]
public class Reader : IUser
{
[Id(...), Column(...), Generator(...)]
public virtual int Id { get; set; }
[Property]
public virtual string Email { get; set; }
}
[Class]
public class ReaderGroup : IUser
{
[Id(...), Column(...), Generator(...)]
public virtual int Id { get; set; }
[ManyToMany(...)]
public virtual ISet<Reader> Readers { get; set; }
}
现在我想实现统一的访问控制机制:
public class AccessPermission
{
[Id(...), Column(...), Generator(...)]
public virtual int Id { get; set; }
public virtual IContent Object { get; set; }
public virtual IUser Subject { get; set; }
}
诀窍是两个字段接受不同类型的值:Object
和Subject
。我之前使用过Discriminator
和Subclass
属性,但之后只有一个字段包含继承类型,而不是两个或更多。
有没有一种聪明的方法来实现这种情况?
答案 0 :(得分:1)
NHibernate并不能很好地使用接口,因为它的工作方式是通过继承实体来创建类的代理(因此你必须将所有字段定义为virtual
)。
我要做的不是你的接口,而是使用抽象类,例如
public abstract class User
{
public virtual int Id { get; protected set; }
public virtual IEnumerable<AccessPermission> AccessPermissions { get; protected set; }
}
然后(使用Fluent NHibernate)
public class UserMap : ClassMap<User>
{
public UserMap()
{
this.Id(x => x.Id);
this.HasMany(x => x.AccessPermissions);
this.DiscriminateSubClassesOnColumn("Type");
}
}
以及您的子类:
public class ReaderMap : SubClassMap<Reader>
{
public ReaderMap()
{
this.DiscriminatorValue("Reader");
this.Map(x => x.Email);
}
}
代表AccessPermission
:
public class AccessPermissionMap : ClassMap<AccessPermission>
{
public AccessPermissionMap()
{
this.Id(x => x.Id);
this.References(x => x.Object);
this.References(x => x.Subject);
}
}
然后NH会为您完成所有艰苦的工作,并根据AccessPermission