我有一个模型,该模型默认具有默认的自动递增ID字段。但是,我希望使用初始数据为数据库添加种子,并且由于存在外键,因此我希望显式设置种子数据的ID。
我的模特
public class EntAttribute
{
public int ID { get; set; }
public string Title { get; set; }
}
我的种子代码:
public class Seeder
{
private class AllAttributes
{
public List<EntAttribute> Attributes { get; set; }
}
public bool SeedData()
{
AllAttributes seedAttributes;
string strSource;
JsonSerializer JsonSer = new JsonSerializer();
strSource = System.IO.File.ReadAllText(@"Data/SeedData/Attributes.json");
seedAttributes = JsonConvert.DeserializeObject<AllAttributes>(strSource);
_context.AddRange(seedAttributes.Attributes);
_context.SaveChanges();
return true;
}
}
请注意,我对EFCore和C#都是陌生的。上面是我设法完成的工作,在我保存更改之前,它似乎一直有效。此时我得到:
SqlException:当IDENTITY_INSERT设置为OFF时,无法在表“属性”中为标识列插入显式值。
现在我很聪明地知道这是因为我无法在EntAttribute表中显式设置ID字段,因为它想通过自动增量分配自己的ID。但是我不够聪明,不知道该怎么办。
任何帮助表示赞赏。
编辑:根据以下公认的答案添加解决方案,因为实际的代码可能会对其他人有所帮助...
因此,我在Context类中添加了以下内容:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasSequence<int>("EntAttributeNumbering")
.StartsAt(10);
modelBuilder.Entity<EntAttribute>()
.Property(i => i.ID)
.HasDefaultValueSql("NEXT VALUE FOR EntAttributeNumbering");
}
这首先确保创建了一个序列(名称是任意的),然后,将其设置为用于相关表而不是自动递增。完成此操作后,便可以获取我的种子数据了。记录少于10条,因此我只需要将序列的起始值设置为10。通常,多一些是有道理的,但是我知道永远不会有更多。
我还必须对迁移进行突击检查,因为它们以某种方式陷入混乱,但这可能无关。
答案 0 :(得分:2)
使用EF Core,您可以创建并使用Sequence对象来分配ID,还可以通过选择序列的开始位置来保留一系列ID以便手动分配。使用序列,您可以自己分配ID,也可以让数据库为您完成ID。
答案 1 :(得分:1)
仅供使用 EF Core 3 的人使用,如果您使用 int 作为您的密钥,您可以设置起始序列值,以防您已播种数据。我发现在我只有一个种子记录的用例中,这可以更清晰地解决这个问题。
例如
modelBuilder.Entity<TableA>()
.Property(p => p.TableAId)
.HasIdentityOptions(startValue: 2);
modelBuilder.Entity<TableA>()
.HasData(
new TableA
{
TableAId = 1,
Data = "something"
});
https://github.com/npgsql/efcore.pg/issues/367#issuecomment-602111259