12

我有一个表,其主键由两列组成,这两列都不是自动递增的,而且我的 Dapper 插入(Dapper 扩展的一部分)在插入时失败,说两列中的第一列不允许 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”中;列不允许空值。插入失败。

出于某种原因,Dapper 没有得到StudentId值为 5 的值。我是否必须为组合了 PK 的表或具有自动递增 PK 的表做一些特别的事情?谢谢。

4

3 回答 3

12

添加 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
    }
} 
于 2014-04-10T20:05:25.267 回答
3

Dapper.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。

于 2020-05-01T21:29:24.623 回答
0

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

您可能必须编写自己的AutoClassMapperhttps ://github.com/tmsmith/Dapper-Extensions/wiki/AutoClassMapper

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

  • AutoClassMapper 假设您的表名是单数的(例如:Car 表名和 Car POCO 名)。
  • 每个 POCO 至少有一个名为 Id 或以 Id 结尾的属性。
  • 如果多个属性以 Id 结尾,Dapper Extensions 将使用第一个 Id 属性作为主键。
  • 如果 Id 属性被确定为 Integer,则 KeyType 将设置为 Identity。
  • 如果 Id 属性被确定为 Guid,则 KeyType 将设置为 Guid。
  • 如果 id 属性不是 Integer 我们的 Guid,则 KeyType 将设置为 Assigned。
于 2014-03-17T19:57:26.340 回答