NHibernate一对一:为AccountDetail生成空id
在使用多对一唯一约束映射一对一关系时,我遇到了一个异常“为AccountDetail生成的null id” 这是我的SQL表: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
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。”。