我有一个以Code
为PK的表格,但在尝试运行该应用程序后,我在 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; }
}
声明的存储库:
private readonly IRepository<Article, string> _articleRepository;
例外:
System.InvalidOperationException:&#39;指定字段&#39; k__BackingField&#39;类型&#39; int&#39;不能用于财产&#39; Article.Id&#39;类型&#39;字符串&#39;。只能使用可从属性类型分配的类型的后备字段。&#39;
我在运行Update-Database
和Add-Migration
时遇到同样的错误。
@aaron非常感谢你的帮助。我已尝试过您建议的步骤,但我在更新和删除记录时遇到错误。
例外:
ERROR 2018-02-12 06:13:23,049 [30] Mvc.ExceptionHandling.AbpExceptionFilter - 发生错误 更新条目。有关详细信息,请参阅内部异常 Microsoft.EntityFrameworkCore.DbUpdateException:发生错误 在更新条目时。有关详细信息,请参阅内部异常---&GT; System.Data.SqlClient.SqlException:无法更新标识列 &#39;标识&#39;
public async Task UpdateTest()
{
var entity = GetAll().Where(x => x.TestId == "One").FirstOrDefault();
await UpdateAsync(entity);
}
public async Task DeleteTest()
{
await DeleteAsync(x => x.TestId == "One");
}
public class Test : FullAuditedEntity
{
// PK
public string TestId { get; set; }
// Unique constraint
public int TestId2 { get; set; }
}
我试图通过引用Disable SoftDelete for AbpUserRole来禁用SoftDelete,但它仍在执行SoftDelete,而不是从DB中删除行。请找截图:
public class TestAppService : MyProjectAppServiceBase, ITestAppService
{
public Task DeleteTest()
{
using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.SoftDelete))
{
return _testRepository.DeleteTest();
}
}
}
MyDBContext.cs :
protected override void CancelDeletionForSoftDelete(EntityEntry entry)
{
if (IsSoftDeleteFilterEnabled)
{
base.CancelDeletionForSoftDelete(entry);
}
}
解决方案工作正常,但在运行测试用例以创建Test
实体时,它会给出以下异常。
SQLite错误19:&#39; NOT NULL约束失败:Test.Id&#39;。
答案 0 :(得分:1)
你的意思是使用varchar类型作为主键吗?只需像这样声明实体类:
public class Article: Entity<string>
{
//You should comment this line
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
//new public int Id { get; set; }
}
然后你可以使用repository:
private readonly IRepository<Article, string> _articleRepository;
答案 1 :(得分:1)
例外是因为您继承了FullAuditedEntity<string>
,指定Id
的类型为string
,然后new
将类型更改为int
。此hiding会导致EF发生冲突。
您可以在这里:
Id
int
列
string
代码:
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;
}
为了完整起见,这个问题是一系列其他Stack Overflow问题中的第一个: