【问题标题】:Dapper insert into table that has a composite PKDapper 插入到具有复合 PK 的表中
【发布时间】:2014-04-23 04:00:42
【问题描述】:

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

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 没有获得值为 5 的 StudentId。我是否必须为组合了 PK 的表或具有 PK 的表做一些特殊的事情自增?谢谢。

【问题讨论】:

  • Dapper 有插入扩展方法吗? Performing Inserts and Updates with Dapper。官方myConn.Execute("INSERT INTO Student (StudentId, StudentName, Active) VALUES (@StudentId, @StudentName, @Active)", new { StudentId = 5, StudentName = "Joe", Active = true});有效吗?
  • 我正在使用 Dapper Extensions 进行插入,这就是引发错误的原因。我刚刚测试了您的建议,并且确实有效。希望只使用扩展方法,因为要输入的文本要少得多。
  • 可以贴一下Insert扩展方法代码吗?是这个吗:github.com/tmsmith/Dapper-Extensions/blob/master/…

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


【解决方案1】:

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

【讨论】:

【解决方案2】:

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。

【讨论】:

  • 虽然这可行,但我必须指出 GetGetAsync GetAllGetAll 不支持复合键。
【解决方案3】:

我不确定这是不是问题,但 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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-26
    • 2016-05-18
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多