Is there a way to map complex types with EF Core

.net .net-core c# entity-framework-core

Question

EF Core does not support Complex types mapping.

If I had an object such as:

public class Entity { 
    public string StringProp {get; set;}
    public SubEntity NestedEntity {get; set;}
}

where SubEntity is :

public class SubEntity{
    public int IntProp {get; set;}
}

How could I map this to a table that has columns for StringProp and IntProp. Basically one record in the table is composed of the properties of both Entity and SubEntity.

I've tried ignoring SubEntity and exposing it's properties in Entity but that doesn't work because when NestedEntity is ignored any properties on Entity using its properties have no values.

Is there any other option than creating a class that has all the properties of the complex type or refactoring the database?

1
4
11/3/2016 8:12:29 PM

Accepted Answer

I have decided to go with a class that contains all the relevant properties and maps to all the required table columns. It works fine as a workaround. Will update when there is support for complex types in EF Core.

2
11/4/2016 10:56:02 PM

Popular Answer

ComplexType mappings are now available since EF Core 2.0. There are currently two ways to do this that I am aware of.

Via Attributes

Not specifying the Column attribute may cause Entity Framework to not map properties to the correct column in existing tables without migrations.

e.g., it may map to Address_StreetAddress

using System.ComponentModel.DataAnnotations.Schema;

public class User
{
    public int Id { get; set; }

    // The complex property we want to use
    public Address Address { get; set; }

    public string UserName{ get; set; }
}

// Lets Entity Framework know this class is a complex type
[ComplexType]
public class Address
{
    // Maps the property to the correct column name
    [Column("Address")]
    public string StreeAddress { get; set; }

    [Column("City")]
    public string City { get; set; }

    [Column("State")]
    public string State { get; set; }

    [Column("Zip")]
    public string ZipCode { get; set; }
}

Via Fluent API

Not specifying the HasColumnName may cause Entity Framework to not map properties to the correct column in existing tables without migrations.

e.g., it may map to Address_StreetAddress

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class MyContext: DbContext
{
    public DbSet<User> Users{ get; set; }

    public MyContext(DbContextOptions<MyContext> options)
        : base(options) { }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<User>(table =>
        {
            // Similar to the table variable above, this allows us to get
            // an address variable that we can use to map the complex
            // type's properties
            table.OwnsOne(
                x => x.Address,
                address =>
                {
                    address.Property(x => x.City).HasColumnName("City");
                    address.Property(x => x.State).HasColumnName("State");
                    address.Property(x => x.StreetAddress).HasColumnName("Address");
                    address.Property(x => x.SuiteNumber).HasColumnName("SuiteNumber");
                    address.Property(x => x.ZipCode).HasColumnName("Zip");
                });
        });
    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow