开发者

Lost inheritance in NHibernate

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);
    }

a开发者_StackOverflownd 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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜