在InMemoryProvider中为自动增量十进制字段配置ValueGenerator

时间:2017-10-16 11:08:03

标签: c# entity-framework entity-framework-core

问题

在我的应用中,我使用的是SQL Server:

services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));

但是当我在单元测试中使用InMemoryProvider时:

[TestInitialize]
public void Initialize()
{
    Services = new ServiceCollection();
    Services.AddDbContext<MyDbContext>(options => options.UseInMemoryDatabase("MyDbContext"), ServiceLifetime.Transient);
    ServiceProvider = Services.BuildServiceProvider();
}

我得到了:

  

System.NotSupportedException:实体类型“Person”上的“PersonId”没有设置值,并且没有值生成器可用于“decimal”类型的属性。在添加实体之前为属性设置值,或者为“decimal”类型的属性配置值生成器。

问题

我在哪里为PersonId属性配置自定义ValueGenerator,以便它只在我使用InMemoryProvider的测试项目中使用?

我拥有什么

我有MS SQL Server数据库和一个带有数字(10,0)类型的自动增量标识列的表。

CREATE TABLE [dbo].[People](
    [Person ID] [numeric](10, 0) IDENTITY(100000000,1) NOT NULL,
 CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED 

和EF代码

[Column("Person ID", TypeName = "numeric(10, 0)")]
public decimal PersonId { get; set; }

public class MyDbContext
{
    public OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>(entity =>
        {
           entity.Property(e => e.PersonId).ValueGeneratedOnAdd();
        });
    }
}

我的应用程序使用SQL Server,但我想设置EF以在测试中使用InMemoryProvider。 Custom ValueGenerator只能在测试中使用

1 个答案:

答案 0 :(得分:4)

从EFC 2.0开始,内存数据库提供程序仅支持整数类型的值生成 - bytesbyteshortushort,{{1} },intuintlong

因此,解决此问题的一种方法是将PK属性映射到适合所需范围的某些类型,例如ulongint等。

但如果你坚持使用long,那么你可以使用以下流畅的设置:

decimal

或者如果你有更多这样的属性,你可以保留现有配置,并在using Microsoft.EntityFrameworkCore.ValueGeneration.Internal; // ... modelBuilder.Entity<Person>(entity => { var pb = entity.Property(e => e.PersonId).ValueGeneratedOnAdd(); if (Database.IsInMemory()) pb.HasValueGenerator<InMemoryIntegerValueGenerator<decimal>>(); }); 覆盖的末尾添加以下内容:

OnModelCreating