Asp.net 如何解决NHibernate中批量更新返回的意外行数错误?

Asp.net 如何解决NHibernate中批量更新返回的意外行数错误?,asp.net,asp.net-mvc,nhibernate,Asp.net,Asp.net Mvc,Nhibernate,在使用NHibernate在数据库中插入新记录时出现以下错误 {“批量更新从更新中返回意外的行数;实际行数:0;应为:1”} 我有两张表,分别是初级关系表和涉外关系表。我想在这两个表中插入记录。下面是映射类 DemoStudentMap.cs public DemoStudentMap() { Table("DEMO_Student"); Id(t => t.StudentId).Column("StudentId").GeneratedB

在使用NHibernate在数据库中插入新记录时出现以下错误

{“批量更新从更新中返回意外的行数;实际行数:0;应为:1”}

我有两张表,分别是初级关系表和涉外关系表。我想在这两个表中插入记录。下面是映射类

DemoStudentMap.cs

 public DemoStudentMap() {
            Table("DEMO_Student");
            Id(t => t.StudentId).Column("StudentId").GeneratedBy.Identity();
            Map(t => t.Name, "Name");
            Map(t => t.Class, "Class");
            Map(t => t.Board, "Board");
            Map(t => t.Enabled, "Enabled");
            Map(t => t.Isdeleted).Column("IsDeleted");
            Map(t => t.Createddate).Column("CreatedDate");
            Map(t => t.Lastmodifyby).Column("LastModifyBy").Nullable();
            Map(t => t.Lastmodifieddate).Column("LastModifiedDate").Nullable();
            References(x => x.DemoScore).ForeignKey("RollNumber");
          }
DemoScoreMap.cs

public DemoScoreMap() {
            Table("DEMO_Score");
            Id(t => t.rollnumber).Column("RollNumber");
            Map(t => t.math, "Math");
            Map(t => t.physics, "Physics");
            Map(t => t.english, "English");
            Map(t => t.enabled, "Enabled");
            Map(t => t.isdeleted).Column("IsDeleted");
            Map(t => t.createddate).Column("CreatedDate");
            Map(t => t.lastmodifyby).Column("LastModifyBy").Nullable();
            Map(t => t.lastmodifieddate).Column("LastModifiedDate").Nullable();
        }
我正在使用Asp.net WebAPI。在Api控制器的Post方法中,我检索了要插入的值。这是我的ApicController:

DemoScoreViewModel newScore = new DemoScoreViewModel();
DemoScore score = newScore.ConvertDemoScoreViewModelToDemoS(newStudent, _crudStatusCreate);
bool resultScore = _demoScoreTask.Create(score);
DemoStudent student = newStudent.ConvertDemoStudentViewModelToDemoStudent(newStudent, score, _crudStatusCreate);
bool result = _demoStudentTask.Create(student);
这里我得到了“score”和“student”变量中的值,我想保存在数据库中。我有以下方法来创建新记录,这些记录返回bool结果,如代码所示

但是在保存数据时,我得到了上面提到的错误。这是我插入的代码。我的成绩和学生成绩都是一样的。以下是我的创建代码:

学生:

 public bool Create(DemoStudent newStudent)
        {
            try
            {
                _demoStudentRepo.DbContext.BeginTransaction();
                _demoStudentRepo.SaveOrUpdate(newStudent);
                _demoStudentRepo.DbContext.CommitTransaction();
            }
            catch
            {
                return false;
            }
            return true;
        }
前场得分

public bool Create(DemoScore newScore)
        {
            try
            {
                _demoScoreRepo.DbContext.BeginTransaction();
                _demoScoreRepo.SaveOrUpdate(newScore);
                _demoScoreRepo.DbContext.CommitTransaction();
            }
            catch
            {
                return false;
            }
            return true;
        }

注意:当我删除事务时,我没有收到此错误,但我的数据仍然没有保存

这里的问题隐藏在一个事实中,即调用了
SaveOrUpdate()
。出于某些原因(稍后讨论),NHibernate决定称之为“更新”。但是因为我们正在创建新的实例,更新的行数。。。是0。在期待1的时候

原因可能是什么?
DemoScore
DemosStudent
在默认的id值和
UnsavedValue
设置中不存在

也就是说,NHibernate期望Id==0意味着新的。。。而任何其他值(甚至负值)都将被视为现有实体。。。应该更新

因此,检查
\u demoScoreTask.Create(score)中的ID分配了什么值

可以在映射中调整默认设置(0表示新设置),例如
.UnsavedValue(-1)


注意:没有事务的版本没有引发异常的原因是没有调用Flush()。请查收。我们可以更改:
sess.FlushMode=FlushMode.Commit设置为Auto,但提交是适当的。

最终解决了问题。错误在映射中

public DemoScoreMap() {
            Table("DEMO_Score");
            Id(t=>t.rollnumber).Column("RollNumber").GeneratedBy.Assigned();
            Map(t => t.math, "Math");
            Map(t => t.physics, "Physics");
            Map(t => t.english, "English");
            Map(t => t.enabled, "Enabled");
            Map(t => t.isdeleted).Column("IsDeleted");
            Map(t => t.createddate).Column("CreatedDate");
            Map(t => t.lastmodifyby).Column("LastModifyBy").Nullable();
            Map(t => t.lastmodifieddate).Column("LastModifiedDate").Nullable();
        }

就我而言,这是身份钥匙。它缺少了由逻辑生成的

改为


因为它显然无法正确创建标识列。所以这是一个映射问题。希望能有所帮助。

您是否已经尝试过此处的建议:我调试了Create函数,发现Id为0。我认为这是正确的。那么它给了我什么错误。((SharpArch.Domain.DomainModel.EntityWithTypedId)(newScore)).Id为0。请尝试显式设置
UnsavedValue(0)
。似乎它被设置为其他对象(-1)。我几乎可以肯定,因为SaveOrUpdate确实会更新。。。(我会说),这一定意味着0没有表示为未保存的值*(注意:唯一的另一个选项可能是Insert返回0行…而不是1行,但在我看来这太复杂了,例如,某些触发器或设置…因此最有可能上面是真的)我必须写入未保存的值(0)。这是映射。但是你知道什么会很有帮助吗。尝试将代码中的SaveOrUpdate更改为Save()。这样,我们将指示NHiberante显式调用INSERT,而不是UPDATE。我们会看看这是否有效。。。如果你知道我的意思。另外,诚实地检查这个映射,这里我很惊讶。通常,如果应该分配标识,NHibernate将发出不带Id的INSERT(RollNumber列),我们应该得到一个异常:try ti INSERT null into not null列。我没有批量返回。。。此外,请记住,一旦您使用
分配的
,您就不应该使用SaveOrUpdate。在这种情况下,NHibernate很难识别分配值与未分配值。。。如下文所述;)不管怎样,祝你好运。。
 Table("JobDetailsBlob");
 Id(x => x.Id, "JobDetailId");
 Table("JobDetailsBlob");
 Id(x => x.Id, "JobDetailId").GeneratedBy.Assigned();