NodaTime如何与EF Code First一起使用?

时间:2014-08-05 16:10:23

标签: entity-framework nodatime

我真的希望能够在我的实体框架代码优先数据库项目中使用NodaTime,但是还没有找到" clean"这样做的方式。我真正想做的是:

public class Photoshoot
{
    public Guid PhotoshootId{get; set;}
    public LocalDate ShootDate{get; set;} //ef ignores this property
}

是否有任何支持或推荐的方法将NodaTime与EF Code First一起使用?

3 个答案:

答案 0 :(得分:19)

在实体框架中本机支持自定义基元类型持久性之前,常见的解决方法是使用伙伴属性

对于域模型中的每个自定义基元,您可以创建关联的映射基元,以便以Entity Framework支持的格式保存值。然后根据相应伙伴属性的值计算自定义原始属性。

例如:

public class Photoshoot
{
    // mapped
    public Guid PhotoshootId{get; set;}

    // mapped buddy property to ShootDate
    public DateTime ShootDateValue { get; set; }

    // non-mapped domain properties
    public LocalDate ShootDate 
    {
        get { // calculate from buddy property }
        set { // set the buddy property }
    }
}

我们在代码中使用NodaTime,首先使用这种方法POCO。

显然,这会让您只使用一种代码作为代码优先POCO和域类型。通过将不同的职责分成两种类型并在它们之间进行映射,可以以牺牲复杂性为代价来改进这一点。中途替代方案是将域属性推送到子类型并使所有映射的伙伴属性受到保护。通过一定数量的wanging Entity Framework可以映射到受保护的属性。

这篇相当精彩的博客文章评估了Entity Framework对各种域建模构造的支持,包括封装的基元。这是我在设置POCO时最初找到伙伴属性的概念: http://lostechies.com/jimmybogard/2014/04/29/domain-modeling-with-entity-framework-scorecard/

该系列中的另一篇博客文章讨论了映射到受保护属性:http://lostechies.com/jimmybogard/2014/05/09/missing-ef-feature-workarounds-encapsulated-collections/

答案 1 :(得分:11)

否"清洁"我知道的方式,因为在撰写本文时,EF doesn't have a mechanism for simple type conversion就像你在NHibernate(IUserType)中看到的那样。作为ORM的EF的真正限制使我改变我的域以适合我的ORM。

答案 2 :(得分:9)

EF Core 2.1具有一项新功能Value Conversions,正是此情况。

//OnModelCreating
builder.Entity<MyEntity>
       .Property(e => e.SomeInstant)
       .HasConversion(v => v.ToDateTimeOffset(), v => Instant.FromDateTimeOffset(v));

.HasConversion还有一些其他重载,以使此逻辑可重复使用,例如,您可以定义自己的ValueConverter