NHibernate一对一:为AccountDetail生成空id

NHibernate一对一:为AccountDetail生成空id,nhibernate,one-to-one,mapping-by-code,Nhibernate,One To One,Mapping By Code,在使用多对一唯一约束映射一对一关系时,我遇到了一个异常“为AccountDetail生成的null id” 这是我的SQL表: Account(Id, Name) AccountDetail(AccountId, Remark) public class Account { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual Accou

在使用多对一唯一约束映射一对一关系时,我遇到了一个异常“为AccountDetail生成的null id

这是我的SQL表:

Account(Id, Name)
AccountDetail(AccountId, Remark)
public class Account
{
    public virtual int Id { get; set; }

    public virtual string Name { get; set; }

    public virtual AccountDetail Detail { get; set; }

    public Account()
    {
        Detail = new AccountDetail
        {
            Account = this
        };
    }
}

public class AccountDetail
{
    public virtual int AccountId { get; set; }

    public virtual Account Account { get; set; }

    public virtual string Remark { get; set; }
}
class AccountMap : ClassMapping<Account>
{
    public AccountMap()
    {
        Table(typeof(Account).Name);

        Id(c => c.Id, m => m.Generator(Generators.Native));

        Property(c => c.Name);

        OneToOne(c => c.Detail, m =>
        {
            m.Constrained(true);
            m.Cascade(Cascade.All);
          m.PropertyReference(typeof(AccountDetail).GetPropertyOrFieldMatchingName("Account"));
        });
    }
}

class AccountDetailMap : ClassMapping<AccountDetail>
{
    public AccountDetailMap()
    {
        Table(typeof(AccountDetail).Name);

        Id(c => c.AccountId, m =>
        {
            m.Column("AccountId");
            m.Generator(Generators.Foreign<AccountDetail>(x => x.Account));
        });

        Property(c => c.Remark);

        ManyToOne(c => c.Account, m =>
        {
            m.Column("AccountId");
            m.Unique(true);
        });
    }
}
AccountId是主键和外键

这是我的域模型(帐户和帐户详细信息):

Account(Id, Name)
AccountDetail(AccountId, Remark)
public class Account
{
    public virtual int Id { get; set; }

    public virtual string Name { get; set; }

    public virtual AccountDetail Detail { get; set; }

    public Account()
    {
        Detail = new AccountDetail
        {
            Account = this
        };
    }
}

public class AccountDetail
{
    public virtual int AccountId { get; set; }

    public virtual Account Account { get; set; }

    public virtual string Remark { get; set; }
}
class AccountMap : ClassMapping<Account>
{
    public AccountMap()
    {
        Table(typeof(Account).Name);

        Id(c => c.Id, m => m.Generator(Generators.Native));

        Property(c => c.Name);

        OneToOne(c => c.Detail, m =>
        {
            m.Constrained(true);
            m.Cascade(Cascade.All);
          m.PropertyReference(typeof(AccountDetail).GetPropertyOrFieldMatchingName("Account"));
        });
    }
}

class AccountDetailMap : ClassMapping<AccountDetail>
{
    public AccountDetailMap()
    {
        Table(typeof(AccountDetail).Name);

        Id(c => c.AccountId, m =>
        {
            m.Column("AccountId");
            m.Generator(Generators.Foreign<AccountDetail>(x => x.Account));
        });

        Property(c => c.Remark);

        ManyToOne(c => c.Account, m =>
        {
            m.Column("AccountId");
            m.Unique(true);
        });
    }
}
映射(NHibenrate 3.3代码映射):

Account(Id, Name)
AccountDetail(AccountId, Remark)
public class Account
{
    public virtual int Id { get; set; }

    public virtual string Name { get; set; }

    public virtual AccountDetail Detail { get; set; }

    public Account()
    {
        Detail = new AccountDetail
        {
            Account = this
        };
    }
}

public class AccountDetail
{
    public virtual int AccountId { get; set; }

    public virtual Account Account { get; set; }

    public virtual string Remark { get; set; }
}
class AccountMap : ClassMapping<Account>
{
    public AccountMap()
    {
        Table(typeof(Account).Name);

        Id(c => c.Id, m => m.Generator(Generators.Native));

        Property(c => c.Name);

        OneToOne(c => c.Detail, m =>
        {
            m.Constrained(true);
            m.Cascade(Cascade.All);
          m.PropertyReference(typeof(AccountDetail).GetPropertyOrFieldMatchingName("Account"));
        });
    }
}

class AccountDetailMap : ClassMapping<AccountDetail>
{
    public AccountDetailMap()
    {
        Table(typeof(AccountDetail).Name);

        Id(c => c.AccountId, m =>
        {
            m.Column("AccountId");
            m.Generator(Generators.Foreign<AccountDetail>(x => x.Account));
        });

        Property(c => c.Remark);

        ManyToOne(c => c.Account, m =>
        {
            m.Column("AccountId");
            m.Unique(true);
        });
    }
}
class AccountMap:ClassMapping
{
公共帐户映射()
{
表(账户类型、名称);
Id(c=>c.Id,m=>m.Generator(Generators.Native));
属性(c=>c.Name);
OneToOne(c=>c.细节,m=>
{
m、 约束(真);
m、 Cascade(Cascade.All);
m、 PropertyReference(typeof(AccountDetail).GetPropertyOrFieldMatchingName(“Account”);
});
}
}
类AccountDetailMap:类映射
{
公共AccountDetailMap()
{
表(类型(AccountDetail).名称);
Id(c=>c.AccountId,m=>
{
m、 列(“AccountId”);
m、 生成器(Generators.Foreign(x=>x.Account));
});
属性(c=>c.Remark);
多通(c=>c.账户,m=>
{
m、 列(“AccountId”);
m、 独特的(真实的);
});
}
}
顺便问一下:我可以删除AccountDetail中的AccountId属性吗?也就是说,只使用Account属性。在AccountDetail类中同时使用AccountId和Account属性看起来不像是面向对象的


谢谢

我说不出到底出了什么问题,但与我工作的一对一关系相比,我会这样映射:

class AccountMap : ClassMapping<Account>
{
    public AccountMap()
    {
        Table(typeof(Account).Name);

        // creates a auto-counter column "id"
        Id(c => c.Id, m => m.Generator(Generators.Native));

        // doesn't require a column, one-to-one always means to couple primary keys.
        OneToOne(c => c.Detail, m =>
        {
            // don't know if this has any effect
            m.Constrained(true);

            // cascade should be fine
            m.Cascade(Cascade.All);
        });
    }
}

class AccountDetailMap : ClassMapping<AccountDetail>
{
    public AccountDetailMap()
    {
        Id(c => c.AccountId, m =>
        {
            // creates an id column called "AccountId" with the value from
            // the Account property.
            m.Column("AccountId");
            m.Generator(Generators.Foreign(x => x.Account));
        });

        // should be one-to-one because you don't use another foreign-key.
        OneToOne(c => c.Account);
    }
}
class AccountMap:ClassMapping
{
公共帐户映射()
{
表(账户类型、名称);
//创建自动计数器列“id”
Id(c=>c.Id,m=>m.Generator(Generators.Native));
//不需要列,一对一始终意味着耦合主键。
OneToOne(c=>c.细节,m=>
{
//不知道这是否有任何影响
m、 约束(真);
//应该没问题
m、 Cascade(Cascade.All);
});
}
}
类AccountDetailMap:类映射
{
公共AccountDetailMap()
{
Id(c=>c.AccountId,m=>
{
//创建一个名为“AccountId”的id列,其值来自
//帐户属性。
m、 列(“AccountId”);
m、 生成器(Generators.Foreign(x=>x.Account));
});
//应该是一对一的,因为您不使用其他外键。
OneTONE(c=>c.Account);
}
}

您是否尝试从映射中删除AccountId?是的,但是如果没有AccountId,我不知道如何进行Id映射。在NHibernate映射中需要Id映射。但是如果这样映射,我们将无法执行延迟加载。一对一关联中不支持延迟加载。请看这个:。我想我现在知道答案了。它需要将外键从子表移动到父表。也就是说,在Account表中添加AccountDetailId。但是从数据库设计者的角度来看,这看起来不太好。顺便说一句:我认为在你的回答中,“约束应该映射到AccountDetailMap,而不是AccountMap。”。