帅气的插入到有复合PK的表中。

问题描述 投票:8回答:3

我有一个表,它的主键由两列组成,两列都不是自动递增的,我的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);

错误:无法在表'dbo.Student'列'StudentId'中插入NULL值。

不能将值NULL插入表'dbo.Student'的'StudentId'列中;该列不允许有空值。INSERT失败。

由于某些原因,Dapper没有得到 "学生 "的信息。StudentId 值为5的表。我是否需要对有组合PK的表或有PK的表做一些特殊的处理? 自动递增?谢谢,我有一个表,它的主键由两列组成,两列都不是自动递增的,我的Dapper插入(Dapper扩展的一部分)失败了。

c# primary-key dapper dapper-extensions
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
    }
} 

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 Extensions "时,你指的是一个不同的扩展库。你可能会发现你可以很容易地切换到Dapper.Contrib。


0
投票

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

你可能需要编写你自己的 AutoClassMapper: https:/github.comtmsmithDapper-ExtensionswikiAutoClassMapper。

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

  • AutoClassMapper假设您的表名是单数(例如:Car表名和Car POCO名)。
  • 每个POCO至少有一个名为Id的属性或以Id结尾。
  • 如果多个属性以Id结尾,Dapper Extensions将使用第一个Id属性作为主键。
  • 如果Id属性被确定为整数,KeyType将被设置为Identity。
  • 如果Id属性被确定为Guid,那么KeyType将被设置为Guid。
  • 如果id属性不是整数而是Guid,那么KeyType将被设置为Assigned。
© www.soinside.com 2019 - 2024. All rights reserved.