C# 如何将Id以外的varchar列用于PK?

C# 如何将Id以外的varchar列用于PK?,c#,entity-framework-core,primary-key,aspnetboilerplate,asp.net-boilerplate,C#,Entity Framework Core,Primary Key,Aspnetboilerplate,Asp.net Boilerplate,我有一个表,它的主键是code,但一旦我尝试运行应用程序,我就会在DefaultEditionCreator.cs中得到下面的异常 [Table("Test")] public class Test: FullAuditedEntity<string> { [DatabaseGenerated(DatabaseGeneratedOption.Identity)] new public int Id { get; set; } [Key] [Datab

我有一个表,它的主键是
code
,但一旦我尝试运行应用程序,我就会在DefaultEditionCreator.cs中得到下面的异常

[Table("Test")]
public class Test: FullAuditedEntity<string>
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    new public int Id { get; set; }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [MaxLength(NVarcharLength14), DataType(DataType.Text)]
    public virtual string Code { get; set; }
}
更新2 我试图通过引用禁用SoftDelete,但它仍在执行SoftDelete,而不是从DB中删除行。请查找屏幕截图:

MyDBContext.cs

protected override void CancelDeletionForSoftDelete(EntityEntry entry)
{
    if (IsSoftDeleteFilterEnabled)
    {
        base.CancelDeletionForSoftDelete(entry);
    }
}
该解决方案工作正常,但在运行测试用例以创建
test
实体时会出现以下异常

SQLite错误19:“非空约束失败:Test.Id”


您的意思是使用varchar类型作为主键吗?只需按如下方式声明实体类:

public class Article: Entity<string>
{
  //You should comment this line
  //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  //new public int Id { get; set; }
}
公共类文章:实体
{
//你应该评论这一行
//[数据库生成(DatabaseGeneratedOption.Identity)]
//新的公共int-Id{get;set;}
}
然后,您可以使用存储库:

private readonly IRepository<Article, string> _articleRepository;
private readonly IRepository\u article存储库;

您的意思是使用varchar类型作为主键吗?只需按如下方式声明实体类:

public class Article: Entity<string>
{
  //You should comment this line
  //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  //new public int Id { get; set; }
}
公共类文章:实体
{
//你应该评论这一行
//[数据库生成(DatabaseGeneratedOption.Identity)]
//新的公共int-Id{get;set;}
}
然后,您可以使用存储库:

private readonly IRepository<Article, string> _articleRepository;
private readonly IRepository\u article存储库;

异常是因为您继承了
FullAuditedEntity
,该属性指定
Id
类型为
string
,然后执行了
new
将类型更改为
int
。这会导致EF发生冲突

以下是您可以做到的:

  • 具有类型为
    int
    的自动递增
    Id
  • 具有类型为
    string
  • 具有唯一的约束列(根据a中的要求)
  • 代码:


    为完整起见,此问题是一系列其他堆栈溢出问题中的第一个:

  • 这个问题。(9月11日)
  • (9月11日)
  • (9月12日)
  • (9月13日)

  • 异常是因为您继承了
    FullAuditedEntity
    ,该属性指定
    Id
    的类型为
    string
    ,然后执行了
    new
    将类型更改为
    int
    。这会导致EF发生冲突

    以下是您可以做到的:

  • 具有类型为
    int
    的自动递增
    Id
  • 具有类型为
    string
  • 具有唯一的约束列(根据a中的要求)
  • 代码:


    为完整起见,此问题是一系列其他堆栈溢出问题中的第一个:

  • 这个问题。(9月11日)
  • (9月11日)
  • (9月12日)
  • (9月13日)
  • private readonly IRepository<Article, string> _articleRepository;
    
    public class Test: FullAuditedEntity
    {
        // PK
        [MaxLength(NVarcharLength14), DataType(DataType.Text)]
        public virtual string Code { get; set; }
    
        // Unique constraint
        public int MyUniqueId { get; set; }
    }
    
    public class AbpProjectNameDbContext : AbpZeroDbContext<Tenant, Role, User, AbpProjectNameDbContext>
    {
        /* Define a DbSet for each entity of the application */    
        public DbSet<Test> Tests { get; set; }
    
        public AbpProjectNameDbContext(DbContextOptions<AbpProjectNameDbContext> options) : base(options) {}
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Entity<Test>().Property(t => t.Id).ValueGeneratedOnAdd(); // Auto-increment
            modelBuilder.Entity<Test>().HasAlternateKey(t => t.Id);                // Auto-increment, closed-wont-fix: https://github.com/aspnet/EntityFrameworkCore/issues/7380
            modelBuilder.Entity<Test>().HasKey(t => t.Code);                       // PK
            modelBuilder.Entity<Test>().HasIndex(t => t.MyUniqueId).IsUnique();    // Unique constraint
        }
    }
    
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "Tests",
            columns: table => new
            {
                Code = table.Column<string>(nullable: false),
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                MyUniqueId = table.Column<int>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Tests", x => x.Code);
            });
    
        migrationBuilder.CreateIndex(
            name: "IX_Tests_MyUniqueId",
            table: "Tests",
            column: "MyUniqueId",
            unique: true);
    }
    
    public async Task MyMethod()
    {
        await _repository.InsertAndGetIdAsync(new Test
        {
            Code = "One",
            MyUniqueId = 1
        });
    
        // Valid
        await _repository.InsertAndGetIdAsync(new Test
        {
            Code = "Two",
            MyUniqueId = 2
        });
    
        try
        {
            await _repository.InsertAndGetIdAsync(new Test
            {
                Code = "One", // PK conflict
                MyUniqueId = 3
            });
        }
        catch (Exception e)
        {
        }
    
        try
        {
            await _repository.InsertAndGetIdAsync(new Test
            {
                Code = "Three",
                MyUniqueId = 1 // Unique constraint conflict
            });
        }
        catch (Exception e)
        {
            throw;
        }
    
        return null;
    }