.net 使用DbContextOptionsBuilder UseModel方法时,无法正确创建实体框架自定义模型构建器

63lcw9qa  于 2023-01-14  发布在  .NET
关注(0)|答案(1)|浏览(199)

我有一个数据库上下文,我想将一些逻辑从另一个文件中的OnModelCreating方法中分离出来。
我在AppDbContext中的当前onModelCreating方法如下所示:

modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
// modelBuilder.Seed();

if (Database.IsSqlite())
{
    var options = new JsonSerializerOptions
    {
        IgnoreNullValues = true, IncludeFields = true
    };
    modelBuilder.Entity<Tenant>()
        .Property(e => e.Profile)
        .HasConversion(
            v => JsonSerializer.Serialize(v, options), 
            v => JsonSerializer.Deserialize<TenantProfile>(v, options)!
        );
}

它工作得非常好,并检查数据库是否是sqlite db,然后我添加了一些额外的逻辑来支持jsonb列序列化/反序列化,因为我的原始数据库使用postgres。
我的单元测试使用了一个Sqlite内存连接。我想将这段代码分隔到一个单独的文件中,所以我创建了一个TestWithSqlite.cs文件,其中包含了我使用DbContextOptionsBuilder UseModel方法配置的自定义模型:

//Create sqlite db model
ModelBuilder modelBuilder = new ModelBuilder(new ConventionSet());
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
var jsonoptions = new JsonSerializerOptions { IgnoreNullValues = true, IncludeFields = true };
modelBuilder.Entity<Tenant>()
    .Property(e => e.Profile)
    .HasConversion(
        v => JsonSerializer.Serialize(v, jsonoptions), 
        v => JsonSerializer.Deserialize<TenantProfile>(v, jsonoptions)!
    );

var model = modelBuilder.Model.FinalizeModel();

var options = new DbContextOptionsBuilder<AppDbContext>()
    .UseModel(model)
    .UseSqlite(_connection)
    .Options;
AppDbContext = new AppDbContext(options, mediatorMock.Object, _auditContext);
AppDbContext.Database.EnsureCreated();

然而,当我现在运行单元测试时,我得到了以下错误:Error
无法Map属性“AppUser.AvatarImage”,因为它的类型为“string”,而该类型不是受支持的基元类型或有效的实体类型。请显式Map此属性,或者使用“[NotMapped]”特性或“OnModelCreating”中的“EntityTypeBuilder.Ignore“忽略它。
字符串属性是原始类型,我想我没有正确配置自定义模型。任何帮助将不胜感激。
编辑:当单元测试遇到AppDbContext.Database.EnsureCreated();方法时,似乎会发生错误

pxiryf3j

pxiryf3j1#

解决方案是我使用了一个带有空ConventionSet的modelBuilder。这个modelBuilder不知道如何正确地Map我的数据。为了解决这个问题,我使用Microsoft.EntityFrameworkCore.MetaData.Conventions命名空间提供的数据库提供程序自定义ConventionSetBuilder示例化了modelBuilder。

ModelBuilder modelBuilder = SqliteConventionSetBuilder.CreateModelBuilder();

相关问题