【问题标题】:JsonElement property can't be mapped in EF Core with SqliteJsonElement 属性不能在 EF Core 中使用 Sqlite 进行映射
【发布时间】:2022-08-19 21:20:38
【问题描述】:

我正在尝试使用内存数据库中的 Sqlite 在基于 Entity Framework Core 5 的项目上运行单元测试,但是在初始化生产 Npgsql Postgres 驱动程序或 EF 都不会发生的 DbContext 时出现错误内核拥有在内存数据库中。

System.InvalidOperationException:\'属性 \'AlertDefinition.Parameters\' 无法映射,因为它的类型为 \'Nullable\',它不是受支持的原始类型或有效的实体类型。要么显式映射此属性,要么使用 \'[NotMapped]\' 属性或使用 \'OnModelCreating\' 中的 \'EntityTypeBuilder.Ignore\' 忽略它。\'

我不确定如何在不影响真正的 Postgres 数据库功能的情况下解决这个问题,它可以按我的意愿工作。

相关实体类

public class AlertDefinition
{
    [Required]
    public JsonElement? Parameters { get; set; }

    public List<AlertOutput>? Outputs { get; set; }
}

public class Rule
{
    public Guid? Id { get; set; }

    [StringLength(254)]
    public string Name { get; set; } = string.Empty;

    [Required]
    public AlertDefinition AlertDefinition { get; set; } = null!;
}

public class RulesDbContext : DbContext
{
    public DbSet<Rule> Rules { get; set; } = null!;

    public DbSet<AlertOutput> AlertOutputs { get; set; } = null!;

    public RulesDbContext(DbContextOptions options)
        : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Define AlertDefinition as an owned entity
        modelBuilder.Entity<Rule>()
            .OwnsOne(r => r.AlertDefinition, adBuilder =>
            {
                adBuilder.OwnsMany(ad => ad.Outputs, oBuilder =>
                {
                    oBuilder.HasKey(o => o.Id);
                    oBuilder.ToTable(\"alert_outputs\");
                });
            });
    }
}

我以前在内存数据库中使用 EF Core,但这不能继续使用,因为我现在正在使用它不支持的功能,并且使用 Postgres 进行单元测试会很困难,如果不是不可能的话需要运行单元测试的 CI。

  • 那么,为什么不启动 Postgres 并针对真实数据库进行测试呢?您将面临提供商之间的许多其他差异。关于集成测试的好读物here
  • 正如我在问题中提到的,Postgres 很难从我们的 CI 服务器基础设施中使用,而且我们有多个没有本地 postgres 安装的开发人员(分散在世界各地)。我们使用 docker 容器在本地运行应用程序,在执行单元测试时不一定要运行,并且很难在每台开发机器上正确安装(并且其中许多在 RAM 中非常受限,所以不希望它一直在运行)。如果我能找到解决方案,能够使用简单的内存数据库就足以满足我们的需求

标签: c# sqlite entity-framework-core .net-5


【解决方案1】:

这是一种不好的做法,但在某些情况下可能很实用:

modelBuilder.Entity<Rule>(entity =>
            {
                if(UnitTestDetector.IsRunningFromNUnit)
                {
                    //unit test mapping
                   entity.Ignore(e => e.Parameters);
                }
                else { "your default mapping" }

UnitTestDetector.IsRunningFromNUnit 假设为 NUnit

【讨论】:

    猜你喜欢
    • 2018-03-06
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 2013-02-14
    • 2020-06-06
    • 1970-01-01
    • 2020-01-01
    • 2021-03-31
    相关资源
    最近更新 更多