为什么代码首先要创建索引列?

时间:2017-07-27 06:08:27

标签: c# sql-server database entity-framework code-first

我有两张如下表:

[Table("MyFlashCard")]
public partial class MyFlashCard
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public MyFlashCard()
    {
        MyFlashCardPics = new HashSet<MyFlashCardPic>();
    }
    public int Id { get; set; }

    public int? FaslID { get; set; }

    public virtual FasleManJdl FasleManJdl { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<MyFlashCardPic> MyFlashCardPics { get; set; }
}

[Table("MyFlashCardPic")]
public partial class MyFlashCardPic
{
    public int Id { get; set; }

    [ForeignKey("MyFlashCard")]
    public int MyFlashCardId { get; set; }

    public virtual MyFlashCard MyFlashCard { get; set; }
}

和ModelBuilder:

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
        modelBuilder.Entity<MyFlashCard>()
            .HasMany(e => e.MyFlashCardPics)
            .WithRequired(e => e.MyFlashCard)
            .HasForeignKey(e => e.MyFlashCardId)
            .WillCascadeOnDelete();
  }

当我添加迁移时,它将创建以下代码:

CreateTable(
            "dbo.MyFlashCardPic",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    MyFlashCardId = c.Int(nullable: false),
                    MyFlashCard_Id = c.Int(),
                    MyFlashCard_Id1 = c.Int(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.MyFlashCard", t => t.MyFlashCard_Id)
            .ForeignKey("dbo.MyFlashCard", t => t.MyFlashCard_Id1)
            .ForeignKey("dbo.MyFlashCard", t => t.MyFlashCardId, cascadeDelete: true)
            .Index(t => t.MyFlashCardId)
            .Index(t => t.MyFlashCard_Id)
            .Index(t => t.MyFlashCard_Id1);

我在MyFlashCardId表格中只有MyFlashCardPic列,但它想要创建另一个列,例如:MyFlashCard_IdMyFlashCard_Id1

我想知道为什么会发生这种情况以及如何阻止它?

如果我从上面的迁移中删除这些列,在创建数据库后(使用update-database命令),当我想使用MyFlashCardPic实体

时,它会抛出以下错误
  

无效的列名称&#39; MyFlashCard_Id1&#39; ,列名称无效&#39; MyFlashCard_Id&#39;

如果我不从迁移中删除这些列,我在编辑flashcard时会出现问题,这个问题与我最近提出的另一个问题相似

How to find out context objects that one entity is attached to?

另一点是没有

[ForeignKey("MyFlashCard")]

属性它将创建3个索引列而不带

modelBuilder.Entity<MyFlashCard>()
            .HasMany(e => e.MyFlashCardPics)
            .WithRequired(e => e.MyFlashCard)
            .HasForeignKey(e => e.MyFlashCardId)
            .WillCascadeOnDelete();

OnModeling中它将创建4个索引列

3 个答案:

答案 0 :(得分:1)

我认为你的问题是你有两个:

[ForeignKey("MyFlashCard")]
public int MyFlashCardId { get; set; }

public virtual MyFlashCard MyFlashCard { get; set; }

添加公共虚拟属性时,提示EF设置外键关系,默认情况下,它使用ClassNameId语法。因为您已经使用相同的名称自己创建了FK,但它仍然认为它必须执行某些操作,因此它会创建另一个作为后缀的1。要解决这个问题,请删除你自己的ForeignKey条目,让EF做它的东西!

修改

我创建了一个新的MVC解决方案。初始数据库是否已创建,然后添加了一个包含以下内容的新类:

using System.Collections.Generic;

using System.ComponentModel.DataAnnotations.Schema;

namespace MVCef.Models
{
    [Table("MyFlashCard")]
    public class MyFlashCard
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public MyFlashCard()
        {
            MyFlashCardPics = new HashSet<MyFlashCardPic>();
        }
        public int Id { get; set; }

        public int? FaslID { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<MyFlashCardPic> MyFlashCardPics { get; set; }
    }

    [Table("MyFlashCardPic")]
    public class MyFlashCardPic
    {
        public int Id { get; set; }

        public virtual MyFlashCard MyFlashCard { get; set; }
    }
}

在IdentityModel中进行了适当的更改,创建了新的迁移,一切正常,如广告所述 - 包括创建外键。我建议您尝试使用新解决方案。我想在某个地方,你已经混淆了EF的地狱!

答案 1 :(得分:0)

您应该删除[ForeignKey(“MyFlashCard”)]属性或停止通过模型构建器进行配置。两者兼顾是造成麻烦的原因。

索引创建如何影响您的所有这些?

答案 2 :(得分:0)

我准确插入了你的模型(我只添加了另一个带有Id和Description属性的缺失类)。我也插入了同一个外键的“双重配置” 这些是EF 6.1.3运行的语句

ExecuteNonQuery==========
CREATE TABLE [FasleManJdls] (
 [Id] int not null identity(1,1)
, [Description] varchar(50) null
);
ALTER TABLE [FasleManJdls] ADD CONSTRAINT [PK_FasleManJdls_873b808d] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [MyFlashCardPic] (
 [Id] int not null identity(1,1)
, [MyFlashCardId] int not null
);
ALTER TABLE [MyFlashCardPic] ADD CONSTRAINT [PK_MyFlashCardPic_873b808d] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [MyFlashCard] (
 [Id] int not null identity(1,1)
, [FaslID] int null
, [FasleManJdl_Id] int null
);
ALTER TABLE [MyFlashCard] ADD CONSTRAINT [PK_MyFlashCard_873b808d] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE INDEX [IX_MyFlashCardId] ON [MyFlashCardPic] ([MyFlashCardId])
ExecuteNonQuery==========
CREATE INDEX [IX_FasleManJdl_Id] ON [MyFlashCard] ([FasleManJdl_Id])
ExecuteNonQuery==========
ALTER TABLE [MyFlashCardPic] ADD CONSTRAINT [FK_MyFlashCardPic_MyFlashCard_MyFlashCardId] FOREIGN KEY ([MyFlashCardId]) REFERENCES [MyFlashCard] ([Id])
ExecuteNonQuery==========
ALTER TABLE [MyFlashCard] ADD CONSTRAINT [FK_MyFlashCard_FasleManJdls_FasleManJdl_Id] FOREIGN KEY ([FasleManJdl_Id]) REFERENCES [FasleManJdls] ([Id])

没有奇怪的列,正如我所料,一个外键([MyFlashCardPic].[MyFlashCardId] REFERENCES [MyFlashCard].[Id]) 我很确定问题出在其他地方。

你正在使用EF吗?

修改
为什么你的课程被标记为部分?你确定你没有其他代码吗?