C# 如何存储DateTime.Now在DateTime2(精度=0)列上以省略毫秒的方式(“归零”)
我正在使用实体框架使用fluent api配置设置表:C# 如何存储DateTime.Now在DateTime2(精度=0)列上以省略毫秒的方式(“归零”),c#,sql,sql-server,entity-framework,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。因此,我希望检索到的日期时间值根本不包括毫秒,即日期应该
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代码)调零毫秒的情况下达到预期效果?如果只需要没有毫秒的日期和时间,请使用
smalldatetime
MS SQL类型。它的精度为1秒
如果出于某种原因,您希望在数据库中包含datetime2,那么您无法自动实现所需的行为。您可以创建一个(计算)属性MyDateTimeWithoutMs,该属性获取并设置数据库连接属性的正确值
internal DateTime databaseDateTime { get; set; }
public DateTime MyDateTimeWithoutMs
{
get
{
return databaseDateTime.DateTimeWithoutMs();
}
set
{
databaseDateTime= value.ToDateTimeWithoutMs();
}
}
在模型映射中,为计算属性添加“忽略”,并将数据库属性映射到实际列名
public class EntryMap : EntityTypeConfiguration<Entry >
{
public Entry Map()
{
Property(t => t.databaseDateTime)
.HasColumnName("DateTime");
Ignore(t => t.MyDateTimeWithoutMs );
公共类入口映射:EntityTypeConfiguration
{
公共入口地图()
{
属性(t=>t.databaseDateTime)
.HasColumnName(“日期时间”);
忽略(t=>t.MyDateTimeWithoutMs);
向@JonSkeet致敬,他向我透露了哪里出了问题。事实证明,我实例化的第一个dbcontext正在进行某种缓存,这反过来又导致提供的日期时间值以毫秒组件完整的状态返回(见图…)。为了获得所需的行为,一种方法是重新实例化db上下文,并在表格基础上启动,以确保不会在datetime返回任何缓存值:
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;
或者,您可以使用.Entry().Reload(),其优点是不需要实例化新的db上下文:
var dbcontext = new ApplicationDbContext(); //foo table is empty
var entry = new Entry { DateTime = DateTime.Now };
dbcontext.Foo.Add();
dbcontext.SaveChanges();
dbcontext.Entry(entry).Reload(); //doesnt suffer from the quirks of dbcontext.Gigs.First()
注:最后但并非最不重要的一点是,如果您在单元测试项目中使用此代码,请确保在尝试之前重建项目(至少我必须这样做才能使项目正常工作)那么您希望EF处理本地对象的截断?在您给出的代码中,不清楚它是否真的要从数据库中检索任何内容…如果您启动一个新的上下文,那么真的,真的提取,它还有毫秒吗?值是多少,如果是的话?请查看,其中的共识是“不,它们不应该”!@RowlandShaw我想我的问题可以归结为精度=0的真正作用是什么?通过阅读说明书,我得到的印象是,这一切都是为了完全降低毫秒数。当然,我很乐意接受更正。你在数据库本身中看到了什么?+1谢谢你关注Sergey。我发现你的方法非常优雅。我对这个问题有了更多的了解我为之讨价还价-我给你!我知道“smalldatetime”,但它不支持datetime2支持的日期范围,所以我想先给datetime2一个机会。再次感谢!