Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can NodaTime be used with EF Code First?

I really want to be able to use NodaTime in my Entity Framework Code First database projects but haven't found a "clean" way to do it. What I really want to do is this:

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

Is there any supported or recommended approach to using NodaTime with EF Code First?

like image 654
smalltowndev Avatar asked Aug 05 '14 16:08

smalltowndev


People also ask

Should I use NodaTime?

Summary. NodaTime is a great library to use if you are building applications where you are handling a lot of date and times. Not only if they are across different time zones, but also if you need to things like time travel and display data at a certain time of the day.

What is code EF?

Then the sound was gone, but the refrigerator was bad to freeze and appeared error code SY EF. This code means that it is not cold enough inside the freezer. After the inspection, it was found that the blades of the Evaporator fan are blocked by ice and the circulation of cold air inside does not occur.


2 Answers

Until custom primitive type persistence is natively supported in Entity Framework, a common work around is to use buddy properties.

For each custom primitive within your domain model, you create an associated mapped primitive to hold the value in a format supported by Entity Framework. The custom primitive properties are then calculated from the value of their corresponding buddy property.

For example:

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 }     } } 

We use NodaTime in our code first POCO's using exactly this approach.

Obviously this leaves you with a single type acting as both a code first POCO and a domain type. This can be improved at the expense of complexity by separating out the different responsibilities into two types and mapping between them. A half-way alternative is to push the domain properties into a subtype and make all mapped buddy properties protected. With a certain amount of wanging Entity Framework can be made to map to protected properties.

This rather splendid blog post evaluates Entity Framework support for various domain modelling constructs including encapsulated primitives. This is where I initially found the concept of buddy properties when setting up our POCO's: http://lostechies.com/jimmybogard/2014/04/29/domain-modeling-with-entity-framework-scorecard/

A further blog post in that series discusses mapping to protected properties: http://lostechies.com/jimmybogard/2014/05/09/missing-ef-feature-workarounds-encapsulated-collections/

like image 178
Matt Caton Avatar answered Oct 23 '22 13:10

Matt Caton


EF Core 2.1 has a new feature Value Conversions, which is exactly for this scenario.

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

.HasConversion has some other overloads to make this logic re-useable, for example you can define your own ValueConverter.

like image 34
Cheng Chen Avatar answered Oct 23 '22 12:10

Cheng Chen