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

EF Core 8中如何设置DateTime类型列的精度?

EF Core 8.0.2 遗留代码重构方案

你的初始方案仅能覆盖原有代码中默认设置datetime2(3)的场景,但丢失了对标记为DateAttribute.Date的属性设置date列类型的逻辑。如果你的项目中存在这类标记了日期类型的属性,直接使用SetPrecision(3)会导致列类型不符合预期;如果没有这类属性,该方案可以正常工作。

以下是更完整的重构实现,完全对齐原有代码的逻辑:

方案一:保留遍历模型的写法

通过EF Core的关系数据库扩展方法,同时处理date和datetime2(3)两种场景:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

foreach (var property in modelBuilder.Model.GetEntityTypes()
             .SelectMany(x => x.GetProperties())
             .Where(x => x.ClrType == typeof(DateTime) || x.ClrType == typeof(DateTime?)))
{
    // 检查属性是否标记了DateAttribute.Date注解
    var dateAnnotation = property.GetAnnotations()
        .Select(x => x.Value is not null ? (string)x.Value : string.Empty)
        .FirstOrDefault(x => x == DateAttribute.Date);

    if (!string.IsNullOrEmpty(dateAnnotation))
    {
        // 设置列类型为SQL的date类型
        property.SetColumnType("date");
    }
    else
    {
        // 设置精度3,对应SQL的datetime2(3)
        property.SetPrecision(3);
    }
}

注意:SetColumnType是Microsoft.EntityFrameworkCore.Relational包中的扩展方法,需要确保项目已引用该包。

方案二:使用EF Core约定(更优雅的现代写法)

通过自定义属性配置约定,自动应用规则,无需手动遍历模型:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class DateTimeColumnConvention : IPropertyConfigurationConvention
{
    public void ProcessPropertyConfiguration(IConventionPropertyBuilder propertyBuilder, IConventionContext<IConventionPropertyBuilder> context)
    {
        var property = propertyBuilder.Metadata;
        // 仅处理DateTime/DateTime?类型属性
        if (property.ClrType != typeof(DateTime) && property.ClrType != typeof(DateTime?))
            return;

        var dateAnnotation = property.GetAnnotations()
            .Select(x => x.Value is not null ? (string)x.Value : string.Empty)
            .FirstOrDefault(x => x == DateAttribute.Date);

        if (!string.IsNullOrEmpty(dateAnnotation))
        {
            propertyBuilder.SetColumnType("date", fromDataAnnotation: false);
        }
        else
        {
            propertyBuilder.SetPrecision(3, fromDataAnnotation: false);
        }
    }
}

// 在DbContext的OnConfiguring中注册约定
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer("你的连接字符串")
        .AddConventions(builder =>
        {
            builder.Add(new DateTimeColumnConvention());
        });
}

关键说明

  • EF Core中,对DateTime类型设置SetPrecision(3)会自动映射为SQL Server的datetime2(3),和原有代码的默认行为完全一致。
  • 对于需要映射为date类型的属性,必须显式调用SetColumnType("date"),因为date类型不支持精度设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 00:26:19