You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.1 DateTime转换代码迁移至.NET 6求助

.NET Core 2.1 迁移至 .NET 6:DateTime Kind 统一为 UTC 的代码适配方案

以下是将原.NET Core 2.1中用于规范化DateTime Kind为UTC的代码迁移至.NET 6的适配方案,核心逻辑保留,仅针对.NET 6的API变化进行调整:

修改后的 DateTimeKindMapper 类

public class DateTimeKindMapper
{
    public static DateTime Normalize(DateTime value) 
        => DateTime.SpecifyKind(value, DateTimeKind.Utc);

    public static DateTime? NormalizeNullable(DateTime? value)
        => value.HasValue ? DateTime.SpecifyKind(value.Value, DateTimeKind.Utc) : null;

    public static object NormalizeObject(object value)
        => value is DateTime dateTime ? Normalize(dateTime) : value;
}

修改后的 DateTimeKindEntityMaterializerSource 类

using Microsoft.EntityFrameworkCore.Query;
using System.Linq.Expressions;
using System.Reflection;

public class DateTimeKindEntityMaterializerSource : EntityMaterializerSource
{
    private static readonly MethodInfo _normalizeMethod =
        typeof(DateTimeKindMapper).GetMethod(nameof(DateTimeKindMapper.Normalize))!;

    private static readonly MethodInfo _normalizeNullableMethod =
        typeof(DateTimeKindMapper).GetMethod(nameof(DateTimeKindMapper.NormalizeNullable))!;

    private static readonly MethodInfo _normalizeObjectMethod =
        typeof(DateTimeKindMapper).GetMethod(nameof(DateTimeKindMapper.NormalizeObject))!;

    public override Expression CreateReadValueExpression(Expression valueBuffer, Type type, int index, IPropertyBase? property = null)
    {
        if (type == typeof(DateTime))
        {
            return Expression.Call(
                _normalizeMethod,
                base.CreateReadValueExpression(valueBuffer, type, index, property));
        }
        if (type == typeof(DateTime?))
        {
            return Expression.Call(
                _normalizeNullableMethod,
                base.CreateReadValueExpression(valueBuffer, type, index, property));
        }
        return base.CreateReadValueExpression(valueBuffer, type, index, property);
    }

    public override Expression CreateReadValueCallExpression(Expression valueBuffer, int index)
    {
        var readValueCallExpression = base.CreateReadValueCallExpression(valueBuffer, index);
        if (readValueCallExpression.Type == typeof(DateTime))
        {
            return Expression.Call(
                _normalizeMethod,
                readValueCallExpression);
        }
        if (readValueCallExpression.Type == typeof(DateTime?))
        {
            return Expression.Call(
                _normalizeNullableMethod,
                readValueCallExpression);
        }
        if (readValueCallExpression.Type == typeof(object))
        {
            return Expression.Call(
                _normalizeObjectMethod,
                readValueCallExpression);
        }
        return readValueCallExpression;
    }
}

关键修改说明

  • 移除GetTypeInfo()调用:.NET 6(以及.NET Core 3.0+)中,Type类直接提供GetMethod方法,无需通过GetTypeInfo()获取成员信息
  • 调整方法签名:基类EntityMaterializerSource的CreateReadValueExpression方法参数从IProperty改为IPropertyBase?(可空类型),需同步重载以匹配基类定义
  • 添加空断言运算符!:由于明确知道目标方法存在,用!消除编译器的可空警告(也可根据需求添加空值检查逻辑)

注册自定义 MaterializerSource

在.NET 6的EF Core配置中,需要将自定义的DateTimeKindEntityMaterializerSource替换默认服务:

// Program.cs 中配置DbContext时注册
builder.Services.AddDbContext<YourDbContext>(options =>
{
    options.UseSqlServer("YourConnectionString");
    options.ReplaceService<IEntityMaterializerSource, DateTimeKindEntityMaterializerSource>();
});

或者在DbContext的OnConfiguring方法中注册:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer("YourConnectionString");
    optionsBuilder.ReplaceService<IEntityMaterializerSource, DateTimeKindEntityMaterializerSource>();
}

内容的提问来源于stack exchange,提问作者Daniel Kaghofer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:25:45