如何在DateTime2(Precision = 0)列上存储DateTime.Now,省略毫秒("归零")

时间:2016-09-13 11:15:38

标签: c# sql sql-server entity-framework

我使用实体框架使用fluent-api配置设置表:

Property(g => g.DateTime).IsRequired().HasColumnType("datetime2").HasPrecision(0);

表确实成功创建了:

CREATE TABLE [dbo].[Foo] (
   [DateTime]     DATETIME2 (0)  NOT NULL,
);

如您所见,datetime2列的精度已设置为0。因此,我希望检索到的日期时间值根本不包括毫秒,也就是说日期应该看起来像2016年3月13日18:35:37.0000'但是,检索的日期总是包括毫秒。以下是我使用的代码:

var dbcontext = new ApplicationDbContext(); //foo table is empty
dbcontext.Foo.Add(new Entry { DateTime = DateTime.Now });
dbcontext.SaveChanges();
var date = dbcontext.Foo.First().DateTime; //this should be identical to DateTime.Now above except for milliseconds which should be set to zero right?

如果不手动调零毫秒(在插入前或检索后通过C#代码),我怎样才能达到预期的效果?

2 个答案:

答案 0 :(得分:1)

如果您只需要没有任何毫秒的日期和时间,请改用smalldatetime MS SQL类型。它的准确度为1秒。

如果出于某种原因,您希望在数据库中使用datetime2,则无法通过自动方式实现所需的行为。您可以创建一个(计算的)属性MyDateTimeWithoutMs来获取并设置数据库连接属性的正确值。

    internal DateTime databaseDateTime { get; set; }
    public DateTime MyDateTimeWithoutMs 
    {
        get
        {
            return databaseDateTime.DateTimeWithoutMs();
        }
        set
        {
            databaseDateTime= value.ToDateTimeWithoutMs();
        }
    }

在模型映射中,为计算属性添加ignore,并将数据库属性映射到实际列名。

public class EntryMap : EntityTypeConfiguration<Entry >
{
    public Entry Map()
    {
        Property(t => t.databaseDateTime)
            .HasColumnName("DateTime");
        Ignore(t => t.MyDateTimeWithoutMs );

答案 1 :(得分:1)

向@JonSkeet致敬,他告诉我什么是错误的。事实证明,我实例化的第一个dbcontext有某种缓存,这反过来导致提供的日期时间值按原样返回,其毫秒组件完好无损(如图...)。解决此问题的一种方法是,为了获得所需的行为,重新实例化db-context并以tabula-rasa为基础,以确保在datetime上不返回任何缓存的值:

Capacity

或者你可以使用.Entry()。Reload(),它的好处是它不需要实例化一个新的db-context:

var dbcontext = new ApplicationDbContext(); //foo table is empty
dbcontext.Foo.Add(new Entry { DateTime = DateTime.Now });
dbcontext.SaveChanges();

var dbcon2 = new ApplicationDbContext(); //vital
var date = dbcon2.Foo.First().DateTime;

PS:最后但并非最不重要的是,如果您在单元测试项目中使用此代码,请务必在给出它之前重建项目(至少我必须做些什么才能让工作在我的项目)