我的nHibernate Mapping-By-Code有一个问题。
表Content
包含FK列“ContentId”引用的表Content_Texts
中的多个条目。
如果我在集合中添加一个带有一个Text的新ContentEntry
,我将获得对内容表执行的第一个查询,但第二个查询(对于Content_Texts)失败,因为NHibernate正在尝试插入Content_Text实体 ContentId = 0 ,在内容表中确实不存在。
这是我的内容表映射:
public class ContentMap : ClassMapping<TContent>
{
#region Constructors
public ContentMap()
{
Table("nfcms_Content");
Schema("dbo");
Lazy(false);
Id<int>(x => x.Id, map => {
map.Generator(Generators.Identity);
});
//Property(x => x.Id, map => map.NotNullable(true));
Property(x => x.Cid, map =>
{
map.NotNullable(false);
});
Property(x => x.CreatorPKID, map => map.NotNullable(false));
Property(x => x.Locked, map => {
map.NotNullable(true);
map.Type(NHibernateUtil.Boolean);
});
Property(x => x.RatingGroupID);
Property(x => x.CDate);
Property(x => x.ContentType, map => map.NotNullable(true));
Property(x => x.ContentRef);
Property(x => x.CreatorSpecialName);
Bag(x => x.Texts, mapping =>
{
mapping.Lazy(CollectionLazy.NoLazy);
mapping.Key(k =>
{
k.Column("ContentId");
});
mapping.Inverse(true);
mapping.Cascade(Cascade.All);
mapping.Fetch(CollectionFetchMode.Select);
},
r => r.OneToMany());
ManyToOne(x => x.User, m =>
{
m.Column(c => c.Name("CreatorPKID"));
m.Fetch(FetchKind.Select);
m.Cascade(Cascade.None);
m.Insert(false);
m.Update(false);
m.Lazy(LazyRelation.NoLazy);
});
ManyToOne(x => x.Category, m =>
{
m.Column(c => c.Name("CID"));
m.Fetch(FetchKind.Select);
m.Cascade(Cascade.None);
m.Insert(false);
m.Update(false);
m.Lazy(LazyRelation.NoLazy);
});
//OneToOne(x => x.Category, map =>
//{
// map.PropertyReference(
// map.Column("CID");
// map.NotFound(NotFoundMode.Ignore);
// map.Cascade(Cascade.None);
//});
//ManyToOne(x => x.User, map =>
//{
// map.PropertyRef("PKID");
// map.Column("CreatorPKID");
// map.Cascade(Cascade.None);
//});
}
#endregion Constructors
}
这里是Content_Text表
public class ContentTextMap : ClassMapping<Persistence.Domain.ContentText>
{
#region Constructors
public ContentTextMap()
{
Table(Ren.CMS.CORE.Config.RenConfig.DB.Prefix +"Content_Text");
Schema("dbo");
Lazy(false);
Id<int>(x => x.Id, map => {
map.Generator(Generators.Identity);
});
Property(x => x.ContentId, map => map.NotNullable(true));
Property(x => x.LangCode, map => map.NotNullable(true));
//Property(x => x.Id, map => map.NotNullable(true));
Property(x => x.Title, map => map.NotNullable(true));
Property(x => x.Seoname);
Property(x => x.MetaKeyWords);
Property(x => x.MetaDescription);
Property(x => x.PreviewText);
Property(x => x.LongText, x => x.Type(NHibernateUtil.StringClob));
//OneToOne(x => x.Category, map =>
//{
// map.PropertyReference(
// map.Column("CID");
// map.NotFound(NotFoundMode.Ignore);
// map.Cascade(Cascade.None);
//});
//ManyToOne(x => x.User, map =>
//{
// map.PropertyRef("PKID");
// map.Column("CreatorPKID");
// map.Cascade(Cascade.None);
//});
}
#endregion Constructors
}
这是NHibernate执行的查询:
NHibernate:INSERT INTO dbo.nfcms_Content(CDate,Cid,ContentRef,ContentType,CreatorPKID,CreatorSpecialName,Locked,RatingGroupID)VALUES(@ p0,@ p1,@ p2,@ p3,@ p4,@ p5,@ p6, @ P7); select SCOPE_IDENTITY(); @ p0 = 27.10.2014 13:51:58 [Type:DateTime(0)],@ p1 = NULL [Type:Guid(0)],@ p2 = 0 [Type:Int32(0)] ,@ p3 ='eNews'[Type:String(4000)],@ p4 = NULL [Type:Guid(0)],@ p5 =''[Type:String(4000)],@ p6 = False [类型:布尔值(0)],@ p7 = 0 [类型:Int32(0)]
NHibernate:INSERT INTO dbo.nfcms_Content_Text(ContentId,LangCode,LongText, MetaDescription,MetaKeyWords,PreviewText,Seoname,Title)VALUES(@ p0,@ p1,@ p2,@ p3,@ p4,@ p5,@ p6,@ p7); select SCOPE_IDENTITY(); @ p0 = 0 [Type:Int32(0)],@ p1 ='de-DE'[Type:String(4000)],@ p2 ='Test'[Type:String(1073741823)], @ p3 ='test'[Type:String(4000)],@ p4 ='test'[Type:String(4000)],@ p5 ='test'[Type:String(4000)],@ p6 ='TEST123455 '[Type:String(4000)],@ p7 ='TEST'[Type:String(4000)]
谁能告诉我什么是错的?我搜查了一下,没有找到任何污垢......
答案 0 :(得分:0)
因为我们确实将one-to-many
关系结束映射为Bag
,其中反向设置(这绝对没问题),如下所示:
public ContentMap()
{
...
Bag(x => x.Texts, mapping =>
{
mapping.Lazy(CollectionLazy.NoLazy);
mapping.Key(k =>
{
k.Column("ContentId");
});
...
我们需要另一端 - 多对一。在我们的情况下,必须由引用 Content
表示(并且也可以表示为只读int
ContentId 强>价值)
public ContentTextMap()
{
ManyToOne(x => x.Content, "ContentId");
Property(x => x.ContentId, map => {
map.Column("ContentId");
map.Update(true);
map.Insert(true);
map.NotNullable(true)
});
...
期待 POCO 是这样的:
public class Content
{
public virtual IList<ContentText> Texts { get; set; }
...
public class ContentText
{
public virtual Content Content { get; set; }
public virtual int ContentId { get; set; }
...
这必须是作业(必须分配两端)
var content = ...;
var contentText = ...;
content.Texts.Add(contentText);// both ends must be assigned
contentText.Content = content; // both ends must be assigned