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

C# 为什么代码首先要创建索引列?,c#,sql-server,database,entity-framework,code-first,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

我有两张表,如下所示:

[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; }
}
我在
MyFlashCardPic
表中只有
myflashcardd
列,但它想创建另一列,如:
MyFlashCard\u Id
MyFlashCard\u Id1

我想知道为什么会发生这种情况,以及如何预防

如果我从上面的迁移中删除这些列,在创建数据库之后(使用updatedatabase命令),当我想使用
MyFlashCardPic
实体时,它将抛出下面的错误

列名“MyFlashCard\u Id1”无效,列名“MyFlashCard\u Id”无效

如果我不从迁移中删除这些列,我在编辑带有图片的抽认卡时会遇到问题,就像我最近遇到的另一个问题一样

另一点是没有

[ForeignKey("MyFlashCard")]
属性,它将创建3个索引列,不带

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

OnModeling
中,它将创建4个索引列

我认为您的问题在于您同时拥有以下两个:

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

添加公共虚拟财产时,您会提示EF设置外键关系,默认情况下,它会使用ClassNameId语法设置外键关系。因为您已经用相同的名称创建了FK,但它仍然认为它必须执行某些操作,因此它创建了另一个后缀为1的FK。要解决这个问题,请删除您自己的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; }
    }
}
使用System.Collections.Generic;
使用System.ComponentModel.DataAnnotations.Schema;
名称空间MVCef.Models
{
[表格(“MyFlashCard”)]
公共类MyFlashCard
{
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2214:DoNotCallOverridableMethodsInConstructors”)]
公共MyFlashCard()
{
MyFlashCardPics=新哈希集();
}
公共int Id{get;set;}
公共int?FaslID{get;set;}
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”,“CA2227:CollectionPropertiesShouldBreadOnly”)]
公共虚拟ICollection MyFlashCardPics{get;set;}
}
[表(“MyFlashCardPic”)]
公共类MyFlashCardPic
{
公共int Id{get;set;}
公共虚拟MyFlashCard MyFlashCard{get;set;}
}
}

在IdentityModel中进行了适当的更改,创建了新的迁移,一切都正常工作,正如广告中所宣传的那样,包括创建外键。我建议你用一个新的解决方案来尝试同样的方法。我想在这条线上的某个地方,你把EF搞糊涂了

您应该删除[ForeignKey(“MyFlashCard”)]属性,或者停止通过model builder对其进行配置。同时做这两件事是你麻烦的原因


索引创建对您的影响如何?

我准确地插入了您的模型(我只添加了另一个缺少Id和描述属性的类)。我还插入了相同外键的“双重配置”。
这些是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]引用[MyFlashCard].[Id]
)。
我很肯定问题出在别的地方

你用的是哪种EF

编辑

为什么您的类被标记为部分?您确定没有其他代码吗?

显然,问题是由此处未显示的内容引起的。创建一个干净的新项目,使用单个db上下文只包含post(和新数据库)中包含的内容,您将看到迁移不会包含这些额外的列。因此,您需要创建。一旦你这样做了,你可能会找到原因。
MyFlashCard
MyFlashCardPic
之间存在一种关系,EF生成默认的FK命名,而不是用户定义的(相关的实体++PK名称)。如果已经存在另一个同名关系,默认情况下EF将添加后缀号以避免重复FK命名。您可以在另一个虚拟项目上尝试找出此行为。也许“addmigration[SOMENAME]-Force”控制台命令可以解决此问题?不,如果没有
[ForeignKey(“MyFlashCard”)]'属性,它将创建3个索引列,如果没有
modelBuilder…`in
OnModeling
它将创建4个索引列
public virtual MyFlashCard MyFlashCard { get; set; }
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; }
    }
}
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])