【问题标题】:Is there a way to map complex types with EF Core有没有办法用 EF Core 映射复杂类型
【发布时间】:2017-03-17 13:16:36
【问题描述】:

EF Core 不支持复杂类型映射。

如果我有一个对象,例如:

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

子实体在哪里:

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

如何将其映射到包含 StringProp 和 IntProp 列的表。基本上表中的一条记录由Entity和SubEntity的属性组成。

我尝试忽略 SubEntity 并在 Entity 中公开它的属性,但这不起作用,因为当忽略 NestedEntity 时,使用其属性的 Entity 上的任何属性都没有值。

除了创建具有复杂类型的所有属性的类或重构数据库之外,还有其他选择吗?

【问题讨论】:

    标签: c# .net entity-framework-core .net-core


    【解决方案1】:

    ComplexType 映射现在从 EF Core 2.0 开始可用。我知道目前有两种方法可以做到这一点。

    通过属性

    未指定 Column 属性可能会导致 Entity Framework 在没有迁移的情况下无法将属性映射到现有表中的正确列。

    例如,它可能映射到 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; }
    }
    

    通过 Fluent API

    未指定 HasColumnName 可能会导致实体框架在没有迁移的情况下无法将属性映射到现有表中的正确列。

    例如,它可能映射到 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");
                    });
            });
        }
    }
    

    【讨论】:

      【解决方案2】:

      我决定使用一个包含所有相关属性和 映射到所有必需的表列。 它可以很好地作为一种解决方法。 当 EF Core 支持复杂类型时会更新。

      【讨论】:

      • 作为一种变通方法,您可以从 complex/valuetype 继承,这样,如果您在多个类中使用它,至少您不必复制属性。
      猜你喜欢
      • 1970-01-01
      • 2015-07-04
      • 2017-11-23
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 2017-05-22
      相关资源
      最近更新 更多