C#实体框架-多个外键

C#实体框架-多个外键,c#,sql,entity-framework,C#,Sql,Entity Framework,EntityFramework6代码首先从我的类中创建多个外键时,它应该只创建一个,但我遇到了一个问题。考虑我有2个班—— public class Work { public Work() { Document1 = new Collection<Document>(); Document2 = new Collection<Document>(); Document3 = new Collection&l

EntityFramework6代码首先从我的类中创建多个外键时,它应该只创建一个,但我遇到了一个问题。考虑我有2个班——

public class Work
{
    public Work()
    {
        Document1 = new Collection<Document>();
        Document2 = new Collection<Document>();
        Document3 = new Collection<Document>();
    }
    [Key]
    public int WorkId { get; set; }
    public virtual ICollection<Document> Document1 { get; set; }
    public virtual ICollection<Document> Document2 { get; set; }
    public virtual ICollection<Document> Document3 { get; set; }
}

public class Document
{
    public int? WorkId { get; set; }
    [ForeignKey("WorkId")]
    public Work Work { get; set; }
}
公共课堂作业
{
公共工作()
{
Document1=新集合();
Document2=新集合();
Document3=新集合();
}
[关键]
公共int工作ID{get;set;}
公共虚拟ICollection Document1{get;set;}
公共虚拟ICollection文档2{get;set;}
公共虚拟ICollection文档3{get;set;}
}
公共类文档
{
公共int?WorkId{get;set;}
[外键(“工作ID”)]
公共工程{get;set;}
}

现在,当我首先运行代码更新数据库命令时,在我的文档表中,它会为工作表工作ID工作Id1工作Id2创建3个不同的外键,这应该只是一个外键,而不是3个外键。我知道应该有一个简单的注释来修复这个问题,或者我需要添加一个流畅的映射?

您的
工作
类有三个
文档
集合,因此
文档
类需要三个键来指示其附加的位置。如果我有一个
Document
的实例,其
WorkId
为4,那么该ID在
Work
的实例上存在于哪里?它属于
Document1
Document2
还是
Document3
?只有一个键,无法确定这一点。实体框架知道这一点,并创建了三个键来解决问题。

显然,
工作
可能有零个或多个
文档1
,零个或多个
文档2
和零个或多个
文档3
。所有这些文件均为Document类型

每个文档只属于一个
工作
,其中它要么是
文档1
,要么是
文档2
,要么是
文档3
。问题是当使用类时,它不知道它是哪种文档类型

最友好、最灵活的解决方案是为每个文档指定一个属性,告诉它是哪种类型的文档,并将所有文档放在一个表中:

public enum DocumentType
{
    Document1,
    Document2,
    Document3,
};

public class Work
{
    public int WorkId { get; set; }
    public virtual ICollection<Document> Document { get; set; }
}

public class Document
{
    public int DocumentId {get; set;} // primary key
    public DocumentType DocumentType {get; set;}

    public int WorkId { get; set; }
    public Work Work { get; set; }
}
public MyDbContext : DbContext
{
    public DbSet<Work> Works {get; set;}
    public DbSet<Document> Documents {get; set;}
}
公共枚举文档类型
{
文件1,
文件2,
文件3,
};
公开课
{
公共int工作ID{get;set;}
公共虚拟ICollection文档{get;set;}
}
公共类文档
{
public int DocumentId{get;set;}//主键
公共DocumentType DocumentType{get;set;}
公共int工作ID{get;set;}
公共工程{get;set;}
}
公共MyDbContext:DbContext
{
公共数据库集工作{get;set;}
公共数据库集文档{get;set;}
}
结果是一个包含文档的表。列WorkId将告诉您文档属于哪个工作。列DocumentType将告诉您它是Document1、Document2还是Document3

这样,添加新的文档类型就很容易,而无需更改数据库。如果您想快速搜索某个类型的所有文档,请考虑使用键(ID、文档类型)< /P>创建额外索引。 如果您确实需要三个不同的表,例如,因为将来Document1可能不再类似于Document2,那么您必须创建三个从Document派生的类,并为这些类创建三个DbSet

public class Document1 : Document
{
   public int WorkId {get; set;}
   public virtual Work Work {get; set;}
}
public MyDbContext : DbContext
{
    public DbSet<Work> Works {get; set;}
    public DbSet<Document1> Document1s {get; set;}
    public DbSet<Document2> Document2s {get; set;}
    public DbSet<Document3> Document3s {get; set;}
}
公共类文档1:文档
{
公共int工作ID{get;set;}
公共虚拟工作{get;set;}
}
公共MyDbContext:DbContext
{
公共数据库集工作{get;set;}
公共DbSet Document1s{get;set;}
公共DbSet Document2s{get;set;}
公共DbSet Document3s{get;set;}
}

考虑为此使用。这样,您将得到一个包含Document1的表、一个包含Document2的表和一个用于Document3的表。

Work
通过三个属性(集合)Document1、Document2和Document3连接到
Document
。这就是它创建三个外键的原因。若您只想指定一个外键,那个么其他两个外键将如何连接到文档实体。