【问题标题】:entity framework code first inheritance property order in generated tables生成表中的实体框架代码优先继承属性顺序
【发布时间】:2015-07-29 23:39:23
【问题描述】:

我首先编写代码,因为我的许多 POCO 对象共享一些属性,所以我决定设置继承。这是我的两个数据对象

public abstract class BaseDataObject
{
    [Key]
    public Guid Id {get; set;}

    public string Name {get; set;}
}

public class DataObject1: BaseDataObject
{
    public string SomeProperty {get; set;}
}

public class DataObject2: BaseDataObject
{
    public string OtherProperty {get; set;}
}

现在,如果 EF 生成我的表,它将创建两个具有以下属性的表

数据对象1 ID(唯一标识符,PK) SomeProperty (nvarchar(max)) 名称 (nvarchar(max))

数据对象2 ID(唯一标识符,PK) 其他属性 (nvarchar(max)) 名称 (nvarchar(max))

所以它把键放在第一位.. 但是我的 BaseDataObject 的另一个属性是在最后添加的。我宁愿在 Id 之后立即拥有这些属性。所以首先是 BaseDataObject 的属性,然后是派生对象的属性。

有没有办法告诉 EF 在生成我的表时这样做?我知道这只是化妆品,但仍然......如果有人直接查看数据库,那么最后拥有这些“基本属性”似乎相当混乱。

谢谢。

【问题讨论】:

  • 你使用迁移吗?

标签: entity-framework inheritance ef-code-first


【解决方案1】:

当我不得不创建复合键时,我偶然发现了一些东西。看来 Column 属性中的 Order 属性可以用来确保生成的表中的某个顺序。

这是我修改 BaseDataObject 的方式

public abstract class BaseDataObject
{
    [Key, Column(Order = 0)]
    public Guid Id {get; set;}

    [Column(Order = 1)]
    public string Name {get; set;}
}

这可确保 Name 列在生成的表中位于 DataObject1 和 DataObject2 的任何属性之后的第二个位置。

【讨论】:

  • 这似乎在具有 2 个级别的层次结构时起作用。我的有 3 个,而 EF 将最高级别的属性放在最新的位置......我尝试了同样的方法,但没有运气。
【解决方案2】:

您可以使用映射文件来执行此操作。当您运行迁移时,它将按该顺序构建表。这将需要每个实体的映射文件。我不知道有什么方法可以在迁移工具中自动设置,而无需映射文件来设置顺序。

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;

namespace YourNamespace.Mapping
{
    public class DataObject1Map : EntityTypeConfiguration<DataObject1>
    {
        public DataObject1Map()
        {
            // Primary Key
            this.HasKey(t => t.Id);

            // Properties
            this.Property(t => t.Name)
                .HasMaxLength(128);

            this.Property(t => t.SomeProperty)
                .IsRequired()
                .HasMaxLength(32);

            // Table & Column Mappings
            this.ToTable("DataObject1");
            this.Property(t => t.Id).HasColumnName("Id");
            this.Property(t => t.Name).HasColumnName("Name");
            this.Property(t => t.SomeProperty).HasColumnName("SomeProperty");
        }
    }
}

//In your context class
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

     modelBuilder.Configurations.Add(new DataObject1Map());

     base.OnModelCreating(modelBuilder);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    相关资源
    最近更新 更多