不能在列、表中插入NULL值;列不允许为空.插入失败

本文关键字:插入 不允许 失败 NULL 不能 | 更新日期: 2023-09-27 18:09:04

我在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)] -无法执行查询:插入标题([TitleID],…), TitleSetID) VALUES (@p0,@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8)选择SCOPE_IDENTITY ()System.Data.SqlClient.SqlException (0x80131904): Cannot insert the列'TitleSetID',表'TitleSetTitle'的NULL值;列不允许为空。插入失败。语句已被终止。

注:

  1. 我使用反向的双向映射
  2. 无论如何逆不服从的东西,根据我的理解,它应该先保存ParantClassData,以确保Child类得到适当的id。
  3. 不确定,我错过了什么

对于上述问题的任何帮助都将非常感谢!

添加了更多的信息来解释这个问题,而不是冗长的代码,我只是想知道是否无论如何TitleSetID只读属性有关的问题。

不能在列、表中插入NULL值;列不允许为空.插入失败

问题实际上隐藏在这个映射中:

HasMany(x => x.TitleSetTitles)
    ...
    .Inverse();

这个映射指示NHibernate:

子节点将关心这个关系。

但这意味着,子节点必须知道它的父节点。

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()映射将工作,因为Parent的ID不再为空

当您试图在列中插入NULL值时,或者忘记在插入语句中包含列时,通常会发生这样的错误,因为某些列设置需要数据,不能留空。请确保在插入语句中包含TitleSetID,并将非null值放入其中。