NHibernate 中失去的继承
我从 EF4 转换为 nHibernate,现在继承方面没有什么问题。
我的实体和映射:
public class User
{
public virtual int Id { get; set; }
public virtual string UserName { get; set; }
}
public class Account
{
public virtual int Id { get; set; }
public virtual User User { get; set; }
}
public class Member : User
{
public virtual string SpecialPropForMember { get; set; }
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id);
Map(x => x.UserName);
}
}
public class AccountMap : ClassMap<Account>
{
public AccountMap()
{
Id(x => x.Id);
References(x => x.User);
}
}
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
Map(x => x.SpecialPropForMember);
}
}
我通过的测试:
[Test]
public void TestMemberUserInheritence()
{
User newUser = new User()
{
UserName = RandomValues.String()
};
Member newMember = new Member()
{
SpecialPropForMember = "special"
};
Account newAccount = new Account()
{
User = newMember
};
Member member = account.User as Member;
Assert.IsNotNull(member);
}
和失败的测试:
[Test]
public void TestMemberUserInheritenceFromNHibernate()
{
User newUser = new User()
{
UserName = RandomValues.String()
};
UsersService().AddUser(newUser);
Member newMember = new Member()
{
SpecialPropForMember = "special"
};
MemberService().Add(newMember);
Account newAccount = new Account()
{
User = newMember
};
AccountService().Add(newAccount);
Account account; ;
using (var session = DataAccess.OpenSession())
{
account = session.Linq<Account>().First();
}
Member member = account.User as Member;
Assert.IsNotNull(member);
}
有人能解释一下为什么 NH 不能正确解析继承吗? 每个类的表和每个层次结构的表也存在同样的问题。
I made conversion from EF4 to nHibernate and now have little problem with inheritence.
My entities and mappings:
public class User
{
public virtual int Id { get; set; }
public virtual string UserName { get; set; }
}
public class Account
{
public virtual int Id { get; set; }
public virtual User User { get; set; }
}
public class Member : User
{
public virtual string SpecialPropForMember { get; set; }
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id);
Map(x => x.UserName);
}
}
public class AccountMap : ClassMap<Account>
{
public AccountMap()
{
Id(x => x.Id);
References(x => x.User);
}
}
public class MemberMap : SubclassMap<Member>
{
public MemberMap()
{
Map(x => x.SpecialPropForMember);
}
}
My passed test:
[Test]
public void TestMemberUserInheritence()
{
User newUser = new User()
{
UserName = RandomValues.String()
};
Member newMember = new Member()
{
SpecialPropForMember = "special"
};
Account newAccount = new Account()
{
User = newMember
};
Member member = account.User as Member;
Assert.IsNotNull(member);
}
and failed test:
[Test]
public void TestMemberUserInheritenceFromNHibernate()
{
User newUser = new User()
{
UserName = RandomValues.String()
};
UsersService().AddUser(newUser);
Member newMember = new Member()
{
SpecialPropForMember = "special"
};
MemberService().Add(newMember);
Account newAccount = new Account()
{
User = newMember
};
AccountService().Add(newAccount);
Account account; ;
using (var session = DataAccess.OpenSession())
{
account = session.Linq<Account>().First();
}
Member member = account.User as Member;
Assert.IsNotNull(member);
}
Could someone explain me why NH don't resolve properly inheritance ?
The same issue is for table per class and table per hierarchy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为 NHibernate 提供延迟加载的方式。失败测试中的 account.User 值实际上是一个代理对象。这意味着,当您加载帐户时,在您访问数据库的任何属性之前,不会从数据库中获取用户(除非您在查询中明确声明)。这意味着,当NHibernate创建代理对象时,它不知道该对象的实际类型是什么,并且它创建直接从User类派生的代理对象。我在这个问题的答案中详细介绍了:强制惰性实体加载真实实例。
It's because of the way that NHibernate provides lazy loading. Value of account.User in your failing test is actually a proxy object. This means, that when you're loading account, the user is not fetched from DB until you access any of it's properties (unless you state so explicitly in your query). This means, that when NHibernate creates the proxy object, it does not know what is actual type of this object, and it creates proxy object that derives directly from User class. I've gone into more details in my anwser to this question: Force lazy entity to load real instance.
NHibernate 中有一个映射选项“lazy = no-proxy”,用于解决该问题的属性。我不确定它是否在 Fluent NHibernate 中可用。
阅读此博客文章了解更多详细信息
http://ayende.com/博客/4378/nhibernate-new-feature-no-proxy-associations
There is a mapping option "lazy = no-proxy" in NHibernate for the property that should fix the problem. I am not sure if it is available in Fluent NHibernate.
Read this blog post for more details
http://ayende.com/blog/4378/nhibernate-new-feature-no-proxy-associations