在尝试将我的实体接口作为“代理”时,我发现了实体代理的奇怪行为。
我使用了以下模型
/* interfaces declaration */
public interface IBaseUser {}
public interface ITeacher : IBaseUser {}
public interface IStudent : IBaseUser {}
public interface IProfile {
public IBaseUser User {get; set;};
}
/* entities implementation */
public abstract class AbstractUser : IBaseUser {}
public class Teacher : AbstractUser, ITeacher {}
public class Student : AbstractUser, IStudent {}
public class Profile : IProfile {
//profile may point to ether Student or Teacher
public virtual IBaseUser User {get; set;}
}
这些实体通过NFluent以编程方式进行映射(小例子如下所示)
/* abstract class mapping declaration example */
class AbstractUserMap : ClassMap<AbstractUser>
{
public AbstractUserMap()
{
//force NHibernate to use interface based proxy
Proxy<IBaseUser>();
DiscriminateSubClassesOnColumn("type").Not.Nullable();
}
}
/* subclass mapping declaration example */
class TeacherMap : SubclassMap<Teacher>
{
public TeacherMap()
{
//force NHibernate to use interface based proxy
Proxy<ITeacher>();
DiscriminatorValue("teacher");
}
}
拥有这些模型我正在尝试按ID
获取个人资料var profile = Session.Get<IProfile>(ID)
在结果中我希望NHibernate在会话缓存中创建2个对象:
[
new Profile {Id = ID, ...},
new IBaseUserProxy {Id = ID1, ...} //<< due to lazy nature of the referenced entity
]
实际上到目前为止一切进展顺利。
但是当我试图检查如何构造IBaseUserProxy
时,我可以看到代理继承了以下接口:
最后两项对我来说完全不清楚。除了ITeacher
之外,为什么NHibernate使用IStudent
和IBaseUser
接口?我知道在构建时确切的代理类型是未知的。但仅仅从最近的接口 - IBaseUser
继承这个代理是不够的呢?
否则,接口的这种“不可能的复合物”会导致以下问题:
profile.User is IBaseUser //true, OK
profile.User is ITeacher //true, OK
profile.User is IStudent //true BUT isn't a true, threw an exception of type 'System.Reflection.TargetException' when you access any property specific to student after casting