Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

EFCore 7 - JSON types- Inserting custom value for DateTime field in JSON column #30892

Closed
shvmgpt116 opened this issue May 15, 2023 · 5 comments

Comments

@shvmgpt116
Copy link

I am running a sample application using sqlserver EFCore provider. The application uses an aggregate type ContactDetails which has a DateTime property DOB.
While inserting some data in the table, I see the associated JSON column has following data.

{
"DOB":"2023-02-03T00:00:00",
"Phone":"01632 12345",
"Address":
	{
	"City":"Camberwick Green",
	"Country":"UK",
	"Postcode":"CW1 5ZH",
	"Street":"1 Main St"
	}
}

Please notice, the DOB field has value 2023-02-03T00:00:00.

I want to ask from database providers perspective if EFCore databse providers have any control over how the values are populated for JSON column.
For Ex:- A database may not understand the DOB field value format in which it is currently inserted, and they may want to insert the DOB field value in a different format.

Tried using converters (For Ex:- using DateTimeToStringConverter) in the provider for the DateTimeTypeMapping doesn't seem a good idea to resolve this since then the converter will be used for the non-JSON DateTime field as well.

For Ex:- If an application has following entities-

public class ContactDetails
    {
      public Address Address { get; set; } = null!;
      public string? Phone { get; set; }
      public DateTime DOB { get; set; }
    }

    public class Address
    {
      public Address(string street, string city, string postcode, string country)
      {
        Street = street;
        City = city;
        Postcode = postcode;
        Country = country;
      }

      public string Street { get; set; }
      public string City { get; set; }
      public string Postcode { get; set; }
      public string Country { get; set; }
    }

    public class Author
    {
      public int Id { get; set; }
      public string Name { get; set; }
      public DateTime JoinDate { get; set; }
      public ContactDetails Contact { get; set; }
    }

Then, Can it be allowed by the database providers to not use any converter for JoinDate property which is a non-JSON property, but use some kind of converter for the DOB property which is a JSON field property, while providing TypeMapping for the entity properties?
Or Is there any other way to achieve this without using converters?
Currently I am not able to do so.

Here is the sample application I am using.

using System;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using System.Collections.Generic;
using System.Reflection.Emit;

namespace test
{
  class Program
  {
    public class ContactDetails
    {
      public Address Address { get; set; } = null!;
      public string? Phone { get; set; }
      public DateTime DOB { get; set; }
    }

    public class Address
    {
      public Address(string street, string city, string postcode, string country)
      {
        Street = street;
        City = city;
        Postcode = postcode;
        Country = country;
      }

      public string Street { get; set; }
      public string City { get; set; }
      public string Postcode { get; set; }
      public string Country { get; set; }
    }

    public class Author
    {
      public int Id { get; set; }
      public string Name { get; set; }
      public DateTime JoinDate { get; set; }
      public ContactDetails Contact { get; set; }
    }

    public class AuthorContext : DbContext
    {
      public DbSet<Author> Authors { get; set; }

      protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
      {
        optionsBuilder
          .UseSqlServer("<conStr>")
        .LogTo(Console.WriteLine);
      }

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
        modelBuilder.Entity<Author>().OwnsOne(
            author => author.Contact, ownedNavigationBuilder =>
            {
              ownedNavigationBuilder.ToJson();
              ownedNavigationBuilder.OwnsOne(contactDetails => contactDetails.Address);
            });
      }

      public static void Main()
      {
        DateTime dt = new DateTime(2023, 2, 3);
        using (var context = new AuthorContext())
        {
          context.Database.EnsureDeleted();
          context.Database.EnsureCreated();

          var author1 = new Author()
          {
            Name = "Maddy Montaquila",
            JoinDate = dt,
            Contact = new ContactDetails()
            {
              Phone = "01632 12345",
              Address = new Address("1 Main St", "Camberwick Green", "CW1 5ZH", "UK"),
              DOB = dt
            }
          };
          context.Authors.Add(author1);
          context.SaveChanges();

          var authorsInChigley = context.Authors.Select(b => b.Contact.DOB)
            .ToList();
        }
      }
    }
  }
}

Include provider and version information

EF Core version: EFCore 7.0.5
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0
Operating system: Windows 10
IDE: Visual Studio 2022 17.4

@frankbuckley
Copy link

This might be covered by: #30677

@shvmgpt116
Copy link
Author

@ajcvickers @roji

@ajcvickers
Copy link
Contributor

@shvmgpt116 This is a limitation of the current code, and is something we are working on.

@roji
Copy link
Member

roji commented May 16, 2023

See also #30727 which discusses specifically the problem with T in timestamp representations, and our general strategy for this.

@roji
Copy link
Member

roji commented May 16, 2023

Duplicate of #30727

@roji roji marked this as a duplicate of #30727 May 16, 2023
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale May 16, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

4 participants