Dapper插入具有复合PK的表中

时间:2014-03-17 18:56:59

标签: c# primary-key dapper dapper-extensions

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

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

错误:

  

无法将值NULL插入“StudentId”列,表'dbo.Student';列不允许空值。 INSERT失败。

Dapper出于某种原因没有得到StudentId的值为5.我是否必须对已经结合PK的表或者具有自动递增?感谢。

3 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:1)

Dapper.Contrib提供了一个注释来解决此问题。

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

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

我假设当您说“ Dapper扩展”时,您指的是一个不同的扩展库。您可能会发现可以轻松切换到Dapper.Contrib。

答案 2 :(得分:0)

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

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

默认的AutoClassMapper对您的数据库模式和POCO做出某些假设:

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