无法将值NULL插入列,表;列不允许空值。 INSERT失败

时间:2014-06-17 16:01:49

标签: c# sql nhibernate fluent-nhibernate

我在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。

  1. 我使用逆向双向映射
  2. 无论如何逆不遵守这些事情,根据我的理解,它应首先保存ParantClassData以确保Child类获得适当的ID。
  3. 不确定,我错过了什么
  4. 对上述问题的任何帮助都将受到热烈欢迎!

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

2 个答案:

答案 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在列表中添加了ChildChild了解Parent.Inverse()映射将起作用,因为父级ID已赢得' t再为null

答案 1 :(得分:-1)

每当您尝试将NULL值插入列时,或者您忘记在insert语句中包含列时,通常会出现类似这样的错误,因为某些列设置需要数据且不能留空。确保您在insert语句中包含TitleSetID,并且在其中添加了非NULL值。