1

我进行了从 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 不能正确解决继承问题吗?同样的问题适用于每个类的表和每个层次结构的表。

4

2 回答 2

2

这是因为 NHibernate 提供延迟加载的方式。失败测试中 account.User 的值实际上是一个代理对象。这意味着,当您加载帐户时,在您访问它的任何属性之前,不会从数据库中获取用户(除非您在查询中如此明确地声明)。这意味着,当 NHibernate 创建代理对象时,它不知道该对象的实际类型是什么,它创建的代理对象直接派生自 User 类。我已经在我的回答中详细介绍了这个问题:Force lazy entity to load real instance

于 2011-08-16T12:51:10.830 回答
1

NHibernate 中有一个映射选项“lazy = no-proxy”,用于应该解决问题的属性。我不确定它是否在 Fluent NHibernate 中可用。

阅读这篇博文了解更多详情

http://ayende.com/blog/4378/nhibernate-new-feature-no-proxy-associations

于 2011-08-16T14:32:19.940 回答