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

时间:2014-01-10 11:03:12

标签: asp.net asp.net-mvc nhibernate

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

{"Batch update returned unexpected row count from update; actual row count: 0; expected: 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方法中,我检索了要插入的值。这是我的ApiController:

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;
        }

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

3 个答案:

答案 0 :(得分:5)

这里的问题隐藏在一个事实中,SaveOrUpdate()被调用。由于某些原因(稍后讨论),NHibernate决定调用“UPDATE”。但是因为我们正在创建实例,更新的行数...是0.虽然期待1

可能是什么原因? DemoScoreDemosStudent确实具有默认 id 值和UnsavedValue设置的incnosistency。

即。 NHibernate期望Id == 0表示新的......而任何其他值(甚至是负数)都将被视为现有实体......应该更新。

因此,请检查为_demoScoreTask.Create(score);

内的ID分配的值

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

注意:为什么版本没有事务没有抛出异常的原因是,没有调用Flush()。请检查9.6. Flush。我们可以将:sess.FlushMode = FlushMode.Commit;更改为自动,但是提交是合适的。

答案 1 :(得分:5)

在我的情况下,它是身份密钥。它缺少.GeneratedBy逻辑。

 Table("JobDetailsBlob");
 Id(x => x.Id, "JobDetailId");

更改为

 Table("JobDetailsBlob");
 Id(x => x.Id, "JobDetailId").GeneratedBy.Assigned();

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

答案 2 :(得分:2)

终于得到了问题。错误发生在Mapping。

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();
        }