0

使用具有唯一约束的多对一映射一对一关系时,出现异常“为 AccountDetail 生成空 id ”。

这是我的 SQL 表:

Account(Id, Name)
AccountDetail(AccountId, Remark)

AccountId 是主键和外键。

这是我的域模型(Account 和 AccountDetail):

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

映射(NHibenrate 3.3 代码映射):

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

顺便说一句:我可以删除 AccountDetail 中的 AccountId 属性吗?也就是说,仅使用 Account 属性。在 AccountDetail 类中同时使用 AccountId 和 Account 属性看起来并不那么面向对象。

谢谢!

4

1 回答 1

1

我不能说实际上出了什么问题,但与我的工作一对一关系相比,我会这样映射它:

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);
    }
}
于 2012-05-14T13:43:06.047 回答