我可以使用 EF Core 5 InMemory 数据库进行集成测试吗

     2023-03-29     148

关键词:

【中文标题】我可以使用 EF Core 5 InMemory 数据库进行集成测试吗【英文标题】:Can I Use EF Core 5 InMemory Database For Integration Testing 【发布时间】:2021-12-17 10:27:20 【问题描述】:

我正在从 net core 3.1 迁移到 net 5(EF Core 3 也迁移到 EF Core 5)。我们正在使用 EF Core 3 InMemory 数据库进行集成测试。迁移测试不再通过并且查询抛出错误后:

System.InvalidOperationException:LINQ 表达式 '形状查询表达式: 查询表达式: 内存查询表达式: 服务器查询表达式: InMemoryTableExpression:实体:RatingExclusionProduct .Where(valueBuffer => IsFalse(ValueBufferTryReadValue(valueBuffer, 0, 属性: RatingExclusion.Id (UUId) 必需 PK AfterSave:Throw).Equals(null)) && 对象.等于( objA:ExpressionExtensions.ValueBufferTryReadValue( 值缓冲:值缓冲, 指数:0, 属性:属性:RatingExclusion.Id (UUId) 必需 PK AfterSave:Throw), objB:ExpressionExtensions.ValueBufferTryReadValue( 值缓冲:值缓冲, 指数:0, 属性:属性:RatingExclusionProduct.ExclusionId (UUId) 必需 PK FK AfterSave:投掷))) 投影映射: 成员:EmptyProjectionMember 投影:EntityProjectionExpression: 属性:RatingExclusionProduct.ExclusionId (UUId) 必需 PK FK AfterSave:Throw -> ExpressionExtensions.ValueBufferTryReadValue( 值缓冲:值缓冲, 指数:0, 属性:属性:RatingExclusionProduct.ExclusionId (UUId) 必需 PK FK 保存后:投掷) 属性:RatingExclusionProduct.ProductId (UUId) 必需 PK FK 索引 AfterSave:Throw -> ExpressionExtensions.ValueBufferTryReadValue( 值缓冲:值缓冲, 指数:1, 属性:属性:RatingExclusionProduct.ProductId (UUId) 必需的 PK FK 索引 保存后:投掷) ,

ShaperExpression: EntityShaperExpression: 
        EntityType: RatingExclusionProduct
        ValueBufferExpression: 
            ProjectionBindingExpression: EmptyProjectionMember
        IsNullable: False

.AsQueryable()
.LeftJoin(
    inner: DbSet<ControlProduct>(), 
    outerKeySelector: o0 => EF.Property<UUId>(o0, "ProductId"), 
    innerKeySelector: c => EF.Property<UUId>(c, "Id"), 
    resultSelector: (o, i) => new TransparentIdentifier<RatingExclusionProduct, ControlProduct>(
        Outer = o, 
        Inner = i
    ))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly

通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”的调用, 或“ToListAsync”

我们能否以某种方式解决这个问题,或者我们需要切换到其他模拟数据库的方法?据我所知,发生了重大变化:

https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/breaking-changes#no-client-methods

我的问题与此有关吗?我在网上搜索过,有些人建议使用真实数据库进行测试,但我担心这会是一个非常缓慢的解决方案,而且我们有多个使用单个数据库的上下文,因此很难在测试开始时创建数据库。有些人建议创建上下文聚合(包含所有实体的单个上下文,仅用于创建数据库),但我不知道如何实现它。我认为我的问题看起来更像是后续问题的组合,但我对这个话题有点迷失了。非常感谢您的关注。

更新: UUId 是自定义类型,它被用作我们所有表的 PK。 为了解决它,我们使用:

    services
        .AddDbContext<RatingsContext>(opt =>
            opt.AddRelationalTypeMappingSourcePlugin<UUIdTypeMapperPlugin>()
                .UseMySql(connectionString, mso => mso
                    .ServerVersion(new Version(5, 7, 29), ServerType.MySql)
                    .EnableRetryOnFailure()
                )
        );

UUIdTypeMapperPlugin 在哪里:

public class UUIdTypeMapperPlugin : ITypeMappingSourcePlugin, IRelationalTypeMappingSourcePlugin

    public CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
    
        return mappingInfo.ClrType == typeof(UUId) ? new UUIdTypeMapper() : null;
    

    public RelationalTypeMapping FindMapping(in RelationalTypeMappingInfo mappingInfo)
    
        return mappingInfo.ClrType == typeof(UUId) ? new UUIdTypeMapper() : null;
    

还有 UUIdTypeMapper:

public class UUIdTypeMapper : RelationalTypeMapping

    private static readonly ValueConverter<UUId, byte[]> _converter
        = new ValueConverter<UUId, byte[]>(uuid => uuid.ToByteArray(),
            byteArray => new UUId(byteArray));

    protected UUIdTypeMapper(RelationalTypeMappingParameters parameters) : base(parameters)
    
    

    public UUIdTypeMapper() : base(new RelationalTypeMappingParameters(
        new CoreTypeMappingParameters(typeof(UUId), _converter), "binary(16)")
    )
    
    

    protected override RelationalTypeMapping Clone(RelationalTypeMappingParameters parameters)
    
        return new UUIdTypeMapper(parameters);
    

    public override string GenerateSqlLiteral(object value)
    
        return $"0xvalue";
    

【问题讨论】:

什么是UUId?听起来像是用作 PK / FK 的自定义类型,很可能是导致问题的原因。 @IvanStoev 我已经更新了关于您的回复的问题 集成测试是什么意思?忘记“官方”定义——含义会根据您的观点而变化。内存提供程序旨在简化单元测试作为 low 保真模拟。它只是一个字典,因此无法模拟复杂的 SQL 操作。仅内存模式的 SQLite 提供程序更好,但 SQLite 过于受限,无法使其成为使用您想要的实际数据库产品进行测试的好选择。它甚至没有正确的数据类型 @PanagiotisKanavos 我们使用内存数据库来测试我们的 WebAPI 的控制器。在更新到 EF Core 5 之前一切正常(我们使用 EF Core 3 没有任何问题)。我知道这不是最好的解决方案,但我们最好需要一些便宜的解决方案 这不是我问的。 为什么您使用自定义 UUID 而不是 Guid?如果我们的 MySQL 提供程序不支持 GUID a) 将 Oracle 的提供程序替换为 Pomelo provider 并且 b) 映射到 Guid,请不要创建新的自定义类型。没有提供者知道如何处理您的自定义类型 【参考方案1】:

经过广泛研究,我发现 EF Core GitHub 上存在与我的问题相关的待处理问题,这是一个错误。

https://github.com/dotnet/efcore/issues/24318

我认为我们的团队应该转向在真实数据库上进行集成测试。有一个有用的链接: https://medium.com/nerd-for-tech/run-ef-core-integration-tests-in-a-repeatable-and-isolated-way-using-a-public-docker-image-with-a-e912a89c7bf4

【讨论】:

我可以避免在 EF Core 中使用迁移吗?

】我可以避免在EFCore中使用迁移吗?【英文标题】:CanIavoidusingmigrationinEFCore?【发布时间】:2021-10-0815:06:30【问题描述】:我正在创建一个ASP.NETWebAPI项目,它从MSSQL数据库中获取数据。使用Scaffold命令后,我拥有所有模型和适当... 查看详情

是否必须使用 .Include 加载 EF Core 5 中的子对象?

】是否必须使用.Include加载EFCore5中的子对象?【英文标题】:Doyouhavetouse.IncludetoloadchildobjectsinEFCore5?【发布时间】:2021-09-0206:50:03【问题描述】:我习惯了EF6,我是EFCore的新手。我正在尝试从与查找表有一些外键关系的表中进行... 查看详情

如何根据 XUnit 测试隔离 EF InMemory 数据库

】如何根据XUnit测试隔离EFInMemory数据库【英文标题】:HowtoisolateEFInMemorydatabaseperXUnittest【发布时间】:2016-12-1719:59:40【问题描述】:我正在尝试使用InMemoryEF7数据库进行xunit存储库测试。但我的问题是,当我尝试处置创建的上下... 查看详情

我可以将依赖项注入迁移(使用 EF-Core 代码优先迁移)吗?

】我可以将依赖项注入迁移(使用EF-Core代码优先迁移)吗?【英文标题】:CanIinjectdependencyintomigration(usingEF-Corecode-firstmigrations)?【发布时间】:2017-07-2710:08:18【问题描述】:我尝试将IConfiguration注入到迁移中(在构造函数中),... 查看详情

具有不同列名的 EF Core 5 HasForeignKey 问题

...e5.0、MSSqlServer我已经在我的数据库中设置了一对多关系(使用HasForeignKey),但是当我尝试使用.Include(x=& 查看详情

EF Core 5 与 Visual Studio for Mac

...forMac【发布时间】:2021-12-1813:44:31【问题描述】:我已经使用docker容器在我的OSX中安装了一个LinuxSQLServer实例,并且我已经使用VSCode连接到这个localhost实例但我需要在VSforMac中连接到它来开发我的EFCore项目,我不知道这是否可能... 查看详情

我可以在生产应用程序中使用 EF Core 2.0 吗?

】我可以在生产应用程序中使用EFCore2.0吗?【英文标题】:IcanuseEFCore2.0inproductionapplications?【发布时间】:2017-08-1209:59:21【问题描述】:Hereinthisblog,他们说.net标准2.0它具有一致性状态。Intheofficialweb,它没有说明.net标准2.0是预... 查看详情

是否可以通过 EF Core 5 在 SQL Server 聚集索引上指定填充因子?

】是否可以通过EFCore5在SQLServer聚集索引上指定填充因子?【英文标题】:Isitpossible/goodtospecifyFillfactoronaSQLServerclusteredindexviaEFCore5?【发布时间】:2021-10-1522:10:38【问题描述】:我正在尝试通过EFCore5迁移创建一个带有字符串主键的... 查看详情

EF Core 5:使用与 FK 相同的 PK 配置拥有的类型且没有父属性

】EFCore5:使用与FK相同的PK配置拥有的类型且没有父属性【英文标题】:EFCore5:ConfiguringownedtypewithPKsameasFKandwithnoparentproperty【发布时间】:2021-10-2203:27:36【问题描述】:我正在尝试迁移到EFCore5。以前一切正常。我不想更改以下结... 查看详情

EF Core 查询优化:我可以在 List<string> 上使用 Contains 吗?

】EFCore查询优化:我可以在List<string>上使用Contains吗?【英文标题】:EFCorequeryoptimization:canIuseContainsonList<string>?【发布时间】:2021-02-2004:36:42【问题描述】:使用EFCore+.NET5.0预览版+Postgres。我正在尝试查找带有某个标签... 查看详情

为啥 EF Core 5 不使用我的实体“地址”的“Id”属性上的“[Key]”属性创建“主键自动增量”?

】为啥EFCore5不使用我的实体“地址”的“Id”属性上的“[Key]”属性创建“主键自动增量”?【英文标题】:WhyEFCore5doesnotcreate"PrimaryKeyAutoincrement"using"[Key]"attributeon"Id"propertyofmyentity"Address"?为什么EFCor... 查看详情

EF Core 5.0 中的多对多关系是不是可以配置为仅保留一个导航属性(在一侧)?

】EFCore5.0中的多对多关系是不是可以配置为仅保留一个导航属性(在一侧)?【英文标题】:Canmany-to-manyrelationshipsinEFCore5.0beconfiguredkeepingjustonenavigationproperty(ononeside)?EFCore5.0中的多对多关系是否可以配置为仅保留一个导航属性(... 查看详情

如何使用 EF Core 5 执行存储过程 ORACLE?

】如何使用EFCore5执行存储过程ORACLE?【英文标题】:HowtoExecuteStoredProcedureORACLEwithEFCore5?【发布时间】:2021-03-0814:01:18【问题描述】:要尝试执行此方法,请启动此错误:Microsoft.EntityFrameworkCore.Database.Command[20102]FailedexecutingDbCommand... 查看详情

在 EF Core 中使用 IsolationLevel 开始事务

...rkCore,但我不知道如何以特定隔离级别开始事务。以前我可以这样做:DbContext.Database.BeginTransaction(IsolationLevel 查看详情

EF Core 5.0 异常无效的对象名称 [TableName]

...ableName]【发布时间】:2021-12-0309:01:52【问题描述】:虽然可以确定表存在,但我收到了无效的对象名称错误。它是一个从4.6转换到Core5的VB.NET应用程序。4.6版本在数据库中查找表。曾经有一行代码初始化数据库。它是Me.Database.SetI... 查看详情

我可以通过在 EF Core 和 SQL Server 中的 OrderBy() 之前使用 Where() 来提高查询的性能吗?

】我可以通过在EFCore和SQLServer中的OrderBy()之前使用Where()来提高查询的性能吗?【英文标题】:CanIincreasetheperformanceofmyquerybyusingWhere()beforeOrderBy()inEFCoreandSQLServer?【发布时间】:2021-06-2308:28:06【问题描述】:我将EntityFrameworkCore与MSS... 查看详情

我可以重用代码来为 EF Core 的子属性选择自定义 DTO 对象吗?

】我可以重用代码来为EFCore的子属性选择自定义DTO对象吗?【英文标题】:CanIreusecodeforselectingacustomDTOobjectforachildpropertywithEFCore?【发布时间】:2021-02-2600:25:43【问题描述】:使用EntityFrameworkCore进行查询时,我使用表达式转换为DT... 查看详情

同时针对 ef core 3.1 和 5 是个好主意吗?

...,它与一个带有2个表的小型数据库交互。我在2个项目中使用过它,1是dotnet5,另一个是旧的dotnet框架4.6,因此我的目标是netstandard2.0,到目前为止它运行良好。我需要将dotnet5中的所有 查看详情