将数据插入到具有复合PK的表中

本文关键字:PK 复合 数据 插入 | 更新日期: 2023-09-27 17:50:36

我有一个由两列组成的主键表,这两列都不是自动递增的,我的Dapper插入(Dapper Extensions的一部分)在插入上失败,说两列中的第一列不允许为空,即使我传递的值不是空。

Student:

StudentId (PK, not null)   '_ (combined to form primary key)
StudentName (PK, not null) /
Active                     -- just another column
c#:

public class Student {
  public int StudentId { get; set; }
  public string StudentName { get; set; }
  public bool Active { get; set; }
}
var newStudent = new Student { StudentId = 5, StudentName = "Joe", Active = true };
var insertSuccess = myConn.Insert<Student>(newStudent);
错误:

不能在表'dbo.Student'列'StudentId'中插入NULL值;列不允许为空。插入失败。

Dapper由于某种原因没有得到值为5的StudentId。对于合并了PK的表,或者对于具有自动递增的PK的表,我是否需要做一些特殊的处理?谢谢。

将数据插入到具有复合PK的表中

添加AutoClassMapper将改变所有类的行为。如果你只想处理这一个类,你可以为这个类创建一个Map。

public class StudentClassMapper : ClassMapper<Student>
{
    public StudentClassMapper()
    {
        Map(x => x.StudentId).Key(KeyType.Assigned);
        Map(x => x.StudentName).Key(KeyType.Assigned);
        AutoMap();  // <-- Maps the unmapped columns
    }
} 

衣冠楚楚。Contrib提供了一个注释来解决这个问题。

public class Student {
  [ExplicitKey]
  public int StudentId { get; set; }
  [ExplicitKey]
  public string StudentName { get; set; }
  public bool Active { get; set; }
}

ExplicitKey表示它是一个必须指定值的关键字段;它不是数据库自动生成的。

我假设当你说"Dapper Extensions"时,你指的是一个不同的扩展库。您可能会发现可以很容易地切换到Dapper.Contrib.

我不确定这是问题所在,但是AFAIK Dapper Extensions默认不支持复合主键。

您可能需要编写自己的AutoClassMapper: https://github.com/tmsmith/Dapper-Extensions/wiki/AutoClassMapper

默认的AutoClassMapper对你的数据库模式和poco做了一些假设:

  • AutoClassMapper假定你的表名是单数的(例如:Car表名和Car POCO名)。
  • 每个POCO至少有一个以Id命名或以Id结尾的属性。
  • 如果多个属性以Id结尾,Dapper Extensions将使用第一个Id属性作为主键。
  • 如果Id属性被确定为整数,则KeyType将被设置为Identity。
  • 如果Id属性被确定为Guid, KeyType将被设置为Guid。
  • 如果id属性不是我们的Guid的整数,KeyType将被设置为Assigned。