4

I followed the documentation on Postgres C# website.

When I run this code I get:

The entity type 'Bar' requires a primary key to be defined.

POCOs:

public class Foo
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public string Name { get; set; }

    [Column(TypeName = "jsonb")]
    public Bar Bar { get; set; }
}

public class Bar
{
    public string Prop1 { get; set; }

    public string Prop2 { get; set; }
}

My goal is to avoid using string as a property type of Bar and let the entity framework handle JSON serialize, deserialize. I don't want the Bar to be a separate table. I want it to be a JSON column on Foo.

Node.JS
  • 1,042
  • 6
  • 44
  • 114
  • I'm pretty sure Entity Framework requires a Primary key (Identity) on every table. (https://stackoverflow.com/questions/3996782/entity-framework-table-without-primary-key) – Ryan Wilson Sep 26 '19 at 19:25
  • But I want it to be a json and I don't want the `Bar` to be an another table – Node.JS Sep 26 '19 at 19:26
  • Even if it's not going to be in the database, it still needs a primary key as a property of your POCO (https://stackoverflow.com/questions/43503424/error-the-entity-type-requires-a-primary-key) – Ryan Wilson Sep 26 '19 at 19:28
  • I added the Id, it creates a new table for `Bar`. I don't want a new table to `Bar`. I want to use a json column – Node.JS Sep 26 '19 at 19:28
  • @NodeJs See answer below – Ryan Wilson Sep 26 '19 at 19:36
  • It shows up as null after adding [NotMapped] because it gets ignored – Node.JS Sep 26 '19 at 19:42
  • Try this post for your needs (https://stackoverflow.com/questions/44829824/how-to-store-json-in-an-entity-field-with-ef-core) – Ryan Wilson Sep 26 '19 at 19:48
  • But these will store json blob as string not a "json". Thanks for the help – Node.JS Sep 26 '19 at 19:51

3 Answers3

4

You need to create ValueConverter<Bar, string> or use function expressions directly in HasConversion in on OnModelCreating.

Example:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Foo>()
        .Property(x => x.Bar)
        .HasConversion(
        v => JsonConvert.SerializeObject(v),
        v => JsonConvert.DeserializeObject<Bar>(v));                

    base.OnModelCreating(modelBuilder);
}

Reference: https://learn.microsoft.com/en-us/ef/core/modeling/value-conversions

pavinan
  • 1,275
  • 1
  • 12
  • 23
2

I ran into this issue with .NET Core 2.1 and MySQL and this is what resolved it for me. I'm not able to update to 3.0 at this time. Adding Ignore was the part that solved my problem.

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Ignore<Bar>();

        modelBuilder.Entity<Foo>()
           .Property(x => x.Bar)
           .HasConversion(
                v => JsonConvert.SerializeObject(v),
                v => JsonConvert.DeserializeObject<Bar>(v))
           .HasColumnType("json");
    }
agritton
  • 1,250
  • 11
  • 15
0

After upgrading to .NET Core 3.0 from 2.2 everything worked fine. The following is the new csproj:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
        <AssemblyName>App</AssemblyName>
        <RootNamespace>App</RootNamespace>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.App" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
        <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.0.0" />
    </ItemGroup>
</Project>
Node.JS
  • 1,042
  • 6
  • 44
  • 114