我正在使用 LINQ to DB 和 linq2db.EntityFrameworkCore 来批量输入一些记录。
使用 EF,我只需在
Id
属性中保存带有 0 的记录,它们使用我在表中设置的序列作为标识符。看来 Linq2DB 不知道 Id
属性是一个标识符。
除了在插入之前为所有记录分配 Id(这可能需要 N 次往返数据库或调用 sp_sequence_get_range)之外,是否有特定的地方可以确保 Linq2DB 知道不要尝试插入 Id?
这使用 Linq2Db 以及 EFC 插件
public async Task AddAsync(IList<Item> items)
{
await AppContext.BulkCopyAsync(new BulkCopyOptions(), items);
}
public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
public void Configure(EntityTypeBuilder<Item> builder)
{
// Primary Key
builder.HasKey(x => x.Id);
builder.Property(x => x.Id)
.HasDefaultValueSql($"NEXT VALUE FOR {BillOfLadingDbContext.ItemIdSequence}")
.HasColumnOrder(0);
// ... snip ....
}
public class Item : SoftDeleteEntityBase
{
// ... snip ...
}
public class SoftDeleteEntityBase : EntityBase, ISoftDeleteEntityBase
{
public bool IsDeleted { get; set; }
}
public class EntityBase : IEntityBase
{
public int Id { get; set; }
// ... snip ...
}
[16:13:34 ERR] 执行请求时发生未处理的异常。 Microsoft.Data.SqlClient.SqlException(0x80131904):违反主键约束“PK_Items”。无法在对象“dbo.Items”中插入重复的键。重复的键值为 (0)。 该声明已终止。
EF 可以默认按照约定识别 Id 列,将其视为 Identity,必须在数据库中设置。使用 Code-First EF 会在支持数据库中将这些标记为身份,因为您使用的是 Linq2Db,您可能需要通过其
[Identity]
属性或 IsIdentity
在 Linq2Db 中显式配置它。 (请参阅Linq2db 身份插入无法按预期工作)如果您有一个架构优先的场景,其中手动创建表创建脚本,那么您将需要将 Id 列设置为身份/自动增量。如果提供程序未自动将 ID 识别为身份列,EF 可能会抱怨,因此您可能还需要 EF 的 [DatabaseGenerated(DatabaseGeneratedOption.Identity]
属性。