您的问题与此页面上用于更改 DateTimes 约定的示例非常相似:Custom Code First Conventions (EF6 onwards)
可能是这样的:
public class TimeSpanConvention : Convention
{
public TimeSpanConvention()
{
this.Properties<TimeSpan>()
.Configure(c => c.HasColumnType("datetime"));
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new TimeSpanConvention());
}
编辑只需重新阅读您的问题,我发现您希望在 C# 代码中使用 DateTime 并在数据库中使用 time(0) ,而不是相反,这样就行不通了。不幸的是,我怀疑您将需要像此解决方案 Convert value when mapping 这样的 2 个字段 - 这确实使数据库属性保持私有。
自定义编码约定但基于命名约定的原始想法如何:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties<DateTime>()
.Where(p => p.Name.EndsWith("TimeOfDay"))
.Configure(p => p.HasColumnType("time(0)"));
}
编辑 2
由于这是一个无效的映射,我们别无选择:
在模型中:
private string DBTimeOfDay { get; set; }
[System.ComponentModel.DataAnnotations.Schema.NotMapped]
public DateTime TimeOfDay
{
get { return new DateTime(DBTimeOfDay.Ticks); }
set { DBTimeOfDay= value.TimeOfDay; }
}
在 Context 类中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ modelBuilder.Types().Configure(c =>
{
var properties = c.ClrType.GetProperties(BindingFlags.NonPublic
| BindingFlags.Instance)
.Where(p => p.Name == "DBTimeOfDay");
foreach (var p in properties)
c.Property(p).HasColumnName("TimeOfDay");
});
}
另一种选择是创建一个数据库视图,在其 sql 中将 time(0) 转换为 DateTime,并映射到修改后的存储过程以进行更新。该技术已被建议用于unsupported data types
编辑 3 !
睡了……这是我的想法。
time(0) 表示一天中的某个时间。
Entity Framework 已选择将其转换为Timespan。
Timespans 应该代表持续时间。
Timespans 很容易添加到DateTimes,结果是一个新的DateTime
C# 没有 TimeOfDay 数据类型
因此,在您的业务逻辑中,您必须将一天中的时间保持为不超过 24 小时的TimeSpan,或者将日期部分设置为任意值的DateTime,然后您将忽略该值。
EF 与 C# 一致,其中 DateTime.TimeOfDay 返回时间跨度
如果您在业务逻辑中进行任何算术运算,例如定期约会等,那么我认为 TimeSpan 实际上可能有一个稍微强一些的论据。如果它很复杂,那么也许你应该开始使用Noda time
当它移动到 UI 时,问题就来了。 TimeEdit 需要 DateTime...我们希望将其显示为 a.m./p.m...
这就是我将它映射到 DateTime 的地方,即在 UI 中。我正在使用 MVC。我正在使用视图模型。我已经从实体映射。我正在使用 AutoMapper。这很容易,并且可以保持实体的清洁。域中的 TimeSpan 属性转换为 UI 的 DateTime..