.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
相关产品推荐
相关产品推荐

