Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to map complex types with EF Core

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?

like image 705
108 Avatar asked Nov 03 '16 20:11

108


People also ask

How do I add a complex type to Entity Framework?

Right-click an entity, point to Add New, and select Complex Property. A complex type property with a default name is added to the entity.

Is EF core faster than EF6?

Note that for a single row, EF Core is slower than EF6 unless using context pooling; this could be the cost of setting up all the scoped services for each instance (which isn't done when context pooling is on). For multiple rows, EF Core batches and EF6 doesn't, so EF Core quickly becomes much faster.

What is Navigation property in EF core?

Navigation property: A property defined on the principal and/or dependent entity that references the related entity. Collection navigation property: A navigation property that contains references to many related entities.


1 Answers

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");
                });
        });
    }
}
like image 131
Blacky Wolf Avatar answered Sep 24 '22 14:09

Blacky Wolf