在 EF Core 中使用未映射类型时如何处理 SQL Server 和 Sqlite 之间的 DateTimeOffset 处理

问题描述 投票:0回答:1

我有一个采用 TPH 策略的表,该策略将许多衍生类型映射到同一个表(这里没有什么不寻常的)。

我使用未映射的类型(未在 EDM 中声明)与原始 SQL(通过

SqlQuery
)结合使用来自基本类型和派生类型的
SELECT
属性(列)。

实体:

public class Base 
{
    public Guid Id { get; set; }
    public DateTimeOffset Created { get; set; }
}

public class A : Base
{
    public string AProperty { get; set; }
}

public class B : Base
{
    public string BProperty { get; set; }
}

未映射类型:

public class Model 
{
    public Guid Id { get; set; }
    public string AProperty { get; set; }
    public string BProperty { get; set; }
    public DateTimeOffset Created { get; set; }
}

查询:

var models = await context.Database.SqlQuery<Model>($"""
     SELECT Id, AProperty, BProperty, Created FROM MyTable
    """);

当我针对 SQL Server 时,一切正常,没有问题。

对于我们的单元测试,我们使用 SQLite;这就是我的问题开始的地方。

首先,SQLite 不支持

DateTimeOffset
,因此在我们的
ApplicationDbContext
中,当
DateTimeOffsetToBinaryConverter
Database.ProviderName
中的
Microsoft.EntityFrameworkCore.Sqlite
时,我们有一个使用
OnModelCreating
的解决方法。

此解决方法非常适合 EDM 中定义的类型,但我为此特定查询 (

Model
) 定义的类型在 EDM 中定义,这意味着未使用该解决方法。

我尝试在

DateTimeOffset
DTO 中将数据类型从
string
切换到
Model
,这实际上对 SQLite 有效,但在 SQL Server 上失败并出现无效的强制转换异常。

我似乎也无法通过注释为特定属性指定转换器;看来只有流畅的配置才能做到这一点。

我在这里能做什么?我感觉有点卡住了..

c# entity-framework-core
1个回答
0
投票

我建议从

DateTimeOffset
切换到
string
并创建如下 DTO:

public class ModelDTO 
{
    public Guid Id { get; set; }
    public string AProperty { get; set; }
    public string BProperty { get; set; }
    public string Created { get; set; }
}

然后让 EF Core 将查询结果映射到一组这样的对象。并将它们转换为

Model
s:

var models = await context.Database.SqlQuery<ModelDTO>($"""
     SELECT Id, AProperty, BProperty, Created FROM MyTable
    """)
    .Select(m => new Model {
        Id = m.Id,
        AProperty = m.AProperty,
        BProperty = m.BProperty,
        Created = DateTimeOffset.Parse(m.Created)
    });
© www.soinside.com 2019 - 2024. All rights reserved.