我在SO上发现了许多类似的问题,我尝试了所有解决方案,但没有一个对我有用,任何人都可以告诉我在下面的代码中出了什么问题,需要做些什么修正才能让它变得可行:
型号:
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; }
}
}
映射:
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]
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:错误 NHibernate.AdoNet.AbstractBatcher [(null)] - 无法执行查询: INSERT INTO TitleSetTitle([TitleID],...,TitleSetID)VALUES(@ p0, @ p1,@ p2,@ p3,@ p4,@ p5,@ p6,@ p7,@ p8);选择SCOPE_IDENTITY() System.Data.SqlClient.SqlException(0x80131904):无法插入 值NULL进入列&#39; TitleSetID&#39;,表&#39; TitleSetTitle&#39 ;;柱 不允许空值。 INSERT失败。声明已经终止。
P.S。
ParantClassData
以确保Child
类获得适当的ID。对上述问题的任何帮助都将受到热烈欢迎!
更新
添加了更多信息来解释问题,而不是冗长的代码,我只是想知道无论如何TitleSetID
readonly属性问题。
答案 0 :(得分:2)
事实上这个问题隐藏在这个映射中:
HasMany(x => x.TitleSetTitles)
...
.Inverse();
这个映射正在指导NHibernate:
chlild会关心这种关系。
但这意味着,那个孩子必须知道它的父母。这段代码不是这样的:
var titleSet = new TitleSetDataEntity
{
Name = "Somename",
...
TitleSetTitles = new List<TitleSetTitleData>
{
new TitleSetTitleData...
},
};
session.Save(titleSet);
在此代码中,new TitleSetTitleData
创建的子实例缺少父引用!这就是问题
注意 - 我猜属性TitleSetTitles属于IList<ChildDataClass1> TitleSetTitles
类型但在代码中我们使用new 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()
映射将起作用,因为父级ID已赢得' t再为null
答案 1 :(得分:-1)
每当您尝试将NULL值插入列时,或者您忘记在insert语句中包含列时,通常会出现类似这样的错误,因为某些列设置需要数据且不能留空。确保您在insert语句中包含TitleSetID
,并且在其中添加了非NULL值。