我有一个亲子关系,我在用户和组之间放了一个测试用例。我这样做是为了复制失败 尝试使用thes关系执行cacade插入时的父子关系。
两个SQL表如下:
CREATE TABLE [dbo].[User]
(
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Name] [varchar](50) NOT NULL,
)
CREATE TABLE [dbo].[Group]
(
[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[GroupName] [varchar](50) NOT NULL,
[UserId] [int] NOT NULL,
)
ALTER TABLE [dbo].[Group] WITH CHECK ADD CONSTRAINT [FK_Group_User] FOREIGN KEY([UserId])
REFERENCES [dbo].[User] ([Id])
对象用以下映射表示这两个表:
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("[User]");
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.Name).Not.Nullable();
HasMany(x => x.Groups).KeyColumn("UserId").Cascade.SaveUpdate();
}
}
public class GroupMap : ClassMap<Group>
{
public GroupMap()
{
Table("[Group]");
Id(x => x.Id).GeneratedBy.Identity();
Map(x => x.GroupName).Not.Nullable();
References(x => x.User).Column("UserId").Not.Nullable();
}
}
创建对象的代码很简单:
用户u =新用户(){Name =“test”}; 组g = new Group(){GroupName =“Test Group”}; u.Groups.Add(克);
using (var session = factory.OpenSession())
{
session.SaveOrUpdate(u);
}
然而它失败,异常“无法将值NULL插入列'UserId',表'test.dbo.Group';列不允许空值.INSERT失败。 该语句已被终止“。我怀疑这是父对象的Id(一个标识列)被传递为NULL而不是新值。这是一个错误还是有办法修复这些映射,以便这个级联关系成功了?
答案 0 :(得分:4)
我最近在项目中使用了这种确切类型的映射。我的建议是:
另一个好建议是更好地封装您的馆藏 - 不要直接访问集合修改方法。集合属性应该是只读的,父节点(在您的情况下为User类)应该具有更改私有集合的AddGroup()和RemoveGroup()方法。为了使其工作,您必须让NHibernate通过使用.Access.CamelCaseField(Prefix.Underscore)或类似的映射属性来访问私有集合成员。 Good discussion about it here
如果需要,我可以发布示例映射和类文件。
答案 1 :(得分:3)
您必须先保存用户,然后将该组分配给用户并保存:
using (var session = factory.OpenSession())
{
User u = new User() { Name = "test"};
session.SaveOrUpdate(u);
Group g = new Group() { GroupName = "Test Group", User = u };
session.SaveOrUpdate(g)
}
我发现你不能级联保存刚刚创建的子/父相关对象。