【问题标题】:Why is EF Code First generating a column for my navigation property?为什么 EF Code First 会为我的导航属性生成一列?
【发布时间】:2017-06-30 17:32:30
【问题描述】:

我试图弄清楚如何配置 EF Code First,以生成表。我遇到的问题是我不确定如何正确配置表。该表与自身具有父子关系。我更喜欢使用 FluentAPI 配置而不是属性的解决方案。

EF 正在生成下表:

Specification
-------------
SpecificationId
Name
ParentSpecificationId
ParentSpecification_SpecificationId

这是课程:

public class Specification
{
    public Specification()
    {
        Children = new Collection<Specification>();
    }

    public int SpecificationId { get; set; }
    public string Name { get; set; }
    public int? ParentSpecificationId { get; set;}
    public virtual Specification ParentSpecification { get; set;}
    public virtual ICollection<Specification> Children { get; set;}
}

我根据this问题尝试了下面的配置

public class SpecificationConfiguration : EntityTypeConfiguration<Specification>
{
    public SpecificationConfiguration()
    {
        ToTable("Specification");
        HasKey(k => k.SpecificationId);
        Property(p => p.SpecificationId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        HasRequired(t => t.ParentSpecification)
        .WithMany(t => t.Children)
        .HasForeignKey(t => t.ParentSpecificationId)
        .WillCascadeOnDelete(false);

        HasOptional(t => t.Children)
        .WithMany()
        .HasForeignKey(t => t.SpecificationId)
        .WillCascadeOnDelete(false);
    }
}

我的配置有什么问题和/或如何让 EF 停止生成 ParentSpecification_SpecificationId 并将值放入 ParentSpecificationId?

注意:EF 将正确的值放入它生成的列中。

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    像这样(EF 6.1.3):

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
    
    
    
        public class Specification
        {
            public int SpecificationId { get; set; }
    
            public string Name { get; set; }
    
            public int? ParentSpecificationId { get; set; }
    
            public virtual Specification ParentSpecification { get; set; }
    
            public virtual ICollection<Specification> Children { get; } = new HashSet<Specification>();
        }
    
        public class Db : DbContext
        {
            public DbSet<Specification> Specifications { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Entity<Specification>()
                            .HasMany(s => s.Children)
                            .WithOptional(s => s.ParentSpecification)
                            .HasForeignKey(s => s.ParentSpecificationId)
                            .WillCascadeOnDelete(false);
    
                base.OnModelCreating(modelBuilder);
            }
        }
    
    
        class Program
        {
            static void Main(string[] args)
            {
    
    
                Database.SetInitializer(new DropCreateDatabaseAlways<Db>());
    
                using (var db = new Db())
                {
                    db.Database.Log = m => Console.WriteLine(m);
    
                    db.Database.Initialize(false);
    
    
                    Console.ReadKey();
                }
            }
        }
    }
    

    输出

        CREATE TABLE [dbo].[Specifications] (
            [SpecificationId] [int] NOT NULL IDENTITY,
            [Name] [nvarchar](max),
            [ParentSpecificationId] [int],
            CONSTRAINT [PK_dbo.Specifications] PRIMARY KEY ([SpecificationId])
        )
    
    
        -- Executing at 6/30/2017 12:54:33 PM -05:00
    
        -- Completed in 24 ms with result: -1
    
    
    
        CREATE INDEX [IX_ParentSpecificationId] ON [dbo].[Specifications]([ParentSpecificationId])
    
    
        -- Executing at 6/30/2017 12:54:33 PM -05:00
    
        -- Completed in 8 ms with result: -1
    
    
    
        ALTER TABLE [dbo].[Specifications] 
        ADD CONSTRAINT [FK_dbo.Specifications_dbo.Specifications_ParentSpecificationId] 
        FOREIGN KEY ([ParentSpecificationId]) 
        REFERENCES [dbo].[Specifications] ([SpecificationId])
    

    【讨论】:

    • 我得到了同样的结果。 EF 仍在生成 4 列。添加记录时,它仍然将 ParentSpecificationId 保留为 null 并填充 ParentSpecification_SpecificationId 列
    • 用完整示例更新了答案。
    • 你知道当你做愚蠢的事情时忘记将你的配置类添加到上下文中,是的,我做到了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 2014-01-20
    • 2022-07-18
    相关资源
    最近更新 更多