如何让 EFCore 内存数据库自动递增非关键字段

Shi*_*ppy 1 .net in-memory-database ef-core-2.2

我们有一个实体以基于自动递增的 int 属性的另一个人类可读的键键控在 guid 上。这在运行应用程序时按预期工作。

出于测试目的,我们使用了 EF 内存数据库,但这似乎只会在列也是键的情况下自动递增。

使用属性注释属性或 fluent API 都没有效果。

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int OrderNumber { get; private set; }

    ===========

    modelBuilder.Entity<Order>(order =>
    {
        order.Property(p => p.OrderNumber).ValueGeneratedOnAdd();
    });
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,插入后 OrderNumber 都保留为 0。有没有办法让内存数据库做到这一点,或者这是一个已知的限制?(谷歌搜索发现了有关重新播种关键值的问题,但不是这个特定问题)

Iva*_*oev 5

非键属性的值生成的工作方式不同(不知道为什么) - 当属性没有分配显式值生成器时不会触发它。对于生成临时密钥的提供程序,它有效,因为实际值是在 之后分配的SaveChanges。但是内存中提供程序值生成器生成持久键,并且由于它们不是为非键属性调用的,ValueGeneratedOnAdd因此没有效果(不起作用)。

解决方法是为此类属性显式分配值生成器。您需要以下命名空间:

using Microsoft.EntityFrameworkCore.InMemory.ValueGeneration.Internal;
Run Code Online (Sandbox Code Playgroud)

然后是类似这样的代码:

modelBuilder.Entity<Order>(order =>
{
    var orderNumber = order.Property(p => p.OrderNumber);
    orderNumber.ValueGeneratedOnAdd();
    // only for in-memory
    if (Database.IsInMemory())
        orderNumber.HasValueGenerator<InMemoryIntegerValueGenerator<int>>();
});
Run Code Online (Sandbox Code Playgroud)