【问题标题】:How to explicitly set the ID property on an autoincrementing table in EFCore如何在 EF Core 中的自动递增表上显式设置 ID 属性
【发布时间】:2018-09-03 15:08:00
【问题描述】:

我有一个默认情况下具有自动递增 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 字段,因为它想通过自动增量分配自己的字段。但我不够聪明,不知道该怎么办。

任何帮助表示赞赏。

编辑:根据下面接受的答案添加解决方案,因为实际代码可能对其他人有所帮助...

所以我在 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。通常更多是有意义的,但我知道永远不会有更多。

我还不得不对我的迁移进行闪电战,因为它们不知何故陷入了混乱,但这可能无关紧要。

【问题讨论】:

    标签: entity-framework ef-core-2.1


    【解决方案1】:

    借助 EF Core,您可以创建和使用 Sequence 对象来分配 ID,并且您可以通过选择序列开始的位置来保留一系列 ID 以进行手动分配。使用序列,您可以自己分配 ID,或者让数据库为您分配。

    【讨论】:

    • 谢谢。这为我指明了正确的方向,而且我有点摸不着头脑,我想通了。一点一点,我慢慢掌握了 EFCore 的窍门……有很多! ://
    【解决方案2】:

    仅供使用 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-20
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2023-03-13
      • 2020-09-20
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多