Models:
public class ParentDataClassData { public ParentDataClassData() { TitleSetTitles = new List<ChildDataClass1>(); TitlesSetEvents = new List<ChildDataClass2>(); } public virtual int TitleSetID { get; set; } public virtual string Name { get; set; } public virtual IList<ChildDataClass1> TitleSetTitles { get; set; } public virtual IEnumerable<ChildDataClass2> TitlesSetEvents { get; set; } public virtual object IdentityField { get { return TitleSetID; } } } public class ChildDataClass1 { public ChildDataClass1() { TitleSet = new ParentDataClassData(); TitleSetTitleEventMedias = new List<TitleSetTitleEventMediaData>(); } public virtual int TitleSetID { get { return TitleSet.TitleSetID; } } public virtual ParentDataClassData TitleSet { get; set; } public virtual IList<TitleSetTitleEventMediaData> TitleSetTitleEventMedias { get; set; } public virtual object IdentityField { get { return TitleSetTitleID; } } } public class ChildDataClass2 { public virtual ParentDataClassData TitleSet { get; set; } public virtual int TitleSetEventID { get; set; } public virtual object IdentityField { get { return TitleSetEventID; } } }
Mappings:
public class ParentDataClassMap : ClassMap<ParentDataEntity> { public ParentDataClassMap() { Table("TitleSet"); LazyLoad(); Id(x => x.TitleSetID) .Column("TitleSetID") .GeneratedBy.Native() .UnsavedValue(0); HasMany(x => x.TitleSetTitles) .LazyLoad() .Inverse() .Fetch.Subselect() .Cascade.SaveUpdate() .KeyColumn("TitleSetID"); HasMany(x => x.TitlesSetEvents) .LazyLoad() .Inverse() .Cascade.SaveUpdate() .Fetch.Subselect() .KeyColumn("TitleSetID"); } } public class ChildDataClass1Map : ClassMap<ChildDataClass1> { public ChildDataClass1Map() { Table("TitleSetTitle"); Id(x => x.TitleSetTitleID) .Column("TitleSetTitleID") .GeneratedBy.Native() .UnsavedValue(0); References(x => x.TitleSet) .Fetch.Join() .Not.Nullable() .Column("TitleSetID") .Cascade.None(); HasMany(x => x.TitleSetTitleEventMedias) .LazyLoad() .Inverse() .Cascade.AllDeleteOrphan() .Fetch.Subselect() .KeyColumn("TitleSetTitleID"); } } public class ChildDataClass2Map : ClassMap<ChildDataClass2> { public ChildDataClass2Map() { Table("TitleSetEvent"); Id(x => x.TitleSetEventID) .Column("TitleSetEventID") .GeneratedBy.Native() .UnsavedValue(0); References(x => x.TitleSet) .Column("TitleSetID") .Not.Update() .Not.Insert() .Cascade.None(); Map(x => x.LengthSec).Not.Nullable(); Map(x => x.EventID).Not.Nullable(); HasMany(x => x.TitleSetDefaultEventMedia) .LazyLoad() .Inverse() .Cascade.None() .Fetch.Join() .KeyColumn("TitleSetEventID"); HasMany(x => x.TitleSetTitleEventMedias) .LazyLoad() .Inverse() .Cascade.None() .Fetch.Join() .KeyColumn("TitleSetEventID"); } }
Test:
[Test] public void CanAddNewTitleSet() { var titleSet = new TitleSetDataEntity { Name = "Somename",ProgramServiceID = 1,CreatedBy = "someuser",CreatedDate = DateTime.Now,ModifiedBy = "someuser",ModifiedDate = DateTime.Now,TitleSetTitles = new List<TitleSetTitleData> { new TitleSetTitleData { IsIncluded = true,IsPremiere = true,TitleTypeCode = "somecode",} },TitlesSetEvents = new List<TitleSetEventData>() }; Session.SaveOrUpdate(titleSet); }
并获得例外:
NHibernate.AdoNet.AbstractBatcher: ERROR
NHibernate.AdoNet.AbstractBatcher [(null)] – Could not execute query:
INSERT INTO TitleSetTitle ([TitleID],…,TitleSetID) VALUES (@p0,
@p1,@p2,@p3,@p4,@p5,@p6,@p7,@p8); select ScopE_IDENTITY()
System.Data.sqlClient.sqlException (0x80131904): Cannot insert the
value NULL into column ‘TitleSetID’,table ‘TitleSetTitle’; column
does not allow nulls. INSERT fails. The statement has been terminated.
附:
>我使用逆向双向映射
>无论如何逆不遵守这些事情,根据我的理解,它应首先保存ParantClassData以确保Child类获得正确的ID.
>不确定,我错过了什么
任何有关上述问题的帮助将受到热烈的赞赏!
更新
添加了更多信息来解释问题,而不是冗长的代码,我只是想知道无论如何TitleSetID readonly属性相关的问题.
解决方法
HasMany(x => x.TitleSetTitles) ... .Inverse();
这个映射正在指导NHibernate:
The chlild will care about this relation.
但这意味着,那个孩子必须知道它的父母.在此代码中不是这样的:
var titleSet = new TitleSetDataEntity { Name = "Somename",... TitleSetTitles = new List<TitleSetTitleData> { new TitleSetTitleData... },}; session.Save(titleSet);
在此代码中,由新TitleSetTitleData创建的子实例缺少父引用!这就是问题所在
注 – 我猜属性TitleSetTitles属于IList< ChildDataClass1>类型. TitleSetTitles但在代码中我们使用新的List< TitleSetTitleData> ……我猜这是一个错字
正确的语法是:
var titleSet = new TitleSetDataEntity { Name = "Somename",... TitleSetTitles = new List<TitleSetTitleData>(); }; var child = new TitleSetTitleData { ... ParentDataClassData = titleSet,}; titleSet.TitleSetTitles.Add(child); session.Save(titleSet);
而现在,NHibernate将拥有足够的信息. Parent在列表中添加了一个Child,Child知道Parent和.Inverse()映射将起作用,因为Parent的ID不再为null
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。