实体框架与额外字段的多对多关系(数据库优先)

时间:2022-10-05 15:18:25

I have a program using Entity Framework (EF) Database First in the data access layer. I know that in order for EF to auto-generate the navigation properties of a many to many relationship, the mapping table needs to contain only a composite primary key:

我有一个程序在数据访问层使用Entity Framework(EF)Database First。我知道为了使EF能够自动生成多对多关系的导航属性,映射表只需要包含一个复合主键:

Project
  - ProjectId (PK)
  - Name

ContentType
  - ContentTypeId (PK)
  - Name

ProjectContentTypeMapping
  - ProjectId (PK)
  - ContentTypeId (PK)

In this case everything works fine, and I can access Projects from ContentTypes and the other way around with navigation properties.

在这种情况下,一切正常,我可以从ContentTypes访问项目,反过来使用导航属性。

However I have a requirement to have extra fields that are particular to the relation between Projects and ContentTypes, and that would be extra columns in the ProjectContentTypeMapping table. Once I add these I loose the navigation properties, and EF shows the mapping table in the designer.

但是,我需要具有特定于Projects和ContentTypes之间关系的额外字段,这将是ProjectContentTypeMapping表中的额外列。一旦我添加了这些,我就会松开导航属性,EF会在设计器中显示映射表。

Is there any way I can manually configure the mapping between these two tables in EF (Database First)? Alternatively, how can I represent this? I was thinking of maybe having an extra "metadata" table with a FK to the mapping table, but it looks "hacky" to me...

有没有办法在EF(数据库优先)中手动配置这两个表之间的映射?或者,我该如何表示?我想到可能有一个带有FK的额外“元数据”表到映射表,但它对我看起来“hacky”...

Thanks

谢谢

1 个解决方案

#1


7  

No, you cannot have extra columns in your mapping table in entity framework. Because, having an extra column implies you intend to use it, but Mapping tables are not part of the entity, so, entity framework, no longer treats your mapping table with extra columns as a Mapping table. You will have to manipulate the Mappings manually.

不,您不能在实体框架中的映射表中添加额外的列。因为,有一个额外的列暗示您打算使用它,但Mapping表不是实体的一部分,因此,实体框架不再将具有额外列的映射表视为Mapping表。您必须手动操作映射。

Lets take example of your classes:

让我们举例说明你的课程:

Project
  - ProjectId (PK)
  - Name
  - ProjectContents

ContentType
  - ContentTypeId (PK)
  - Name
  - ProjectContents

ProjectContentTypeMapping
  - ProjectId (PK)
  - ContentTypeId (PK)
  - OtherRelevantColumn

where ProjectContents is of type ProjectContentTypeMapping

其中ProjectContents的类型为ProjectContentTypeMapping

so whenever you add a Project with Certain ContentType, you would be doing this:

因此,无论何时添加具有某些ContentType的项目,您都会这样做:

Project prj = new Project();
//fill out scalar properties
ProjectContentTypeMapping pctm = new ProjectContentTypeMapping();
pctm.ContentTypeId = 1; //or whatever you want, or selected from UI

prj.ProjectContents = new ProjectContentTypeMapping();
prj.ProjectContents.Add(pctm);

dataContext.Projects.Add(prj);

Now in case of editing (adding ContentTypes) to an existing project, you won't do prj.ProjectContents = new ... rather, you would do it only when it is null i,e,

现在在编辑(添加ContentTypes)到现有项目的情况下,你不会做prj.ProjectContents = new ...相反,你只会在它为null时执行它,e,e,

if(prj.ProjectContents==null)
   prj.ProjectContents = new ProjectContentTypeMapping();

also, one very very important thing, since now your ProjectContentTypeMapping is no longer a mapping table, so, deleting a Project would give you an error, if its id is being present in ProjectContentTypeMapping table; you will have to remove them manually i.e

另外,一个非常重要的事情,因为现在你的ProjectContentTypeMapping不再是一个映射表,因此,如果Project的内容出现在ProjectContentTypeMapping表中,删除一个Project会给你一个错误;你必须手动删除它们,即

foreach(var pctm in prj.ProjectContents.ToList())
{
   prj.ProjectContents.Remove(pctm);
   datacontext.ProjectContentTypeMappings.Remove(pctm);
}
datacontext.Remove(prj);
datacontext.SaveChanges();

#1


7  

No, you cannot have extra columns in your mapping table in entity framework. Because, having an extra column implies you intend to use it, but Mapping tables are not part of the entity, so, entity framework, no longer treats your mapping table with extra columns as a Mapping table. You will have to manipulate the Mappings manually.

不,您不能在实体框架中的映射表中添加额外的列。因为,有一个额外的列暗示您打算使用它,但Mapping表不是实体的一部分,因此,实体框架不再将具有额外列的映射表视为Mapping表。您必须手动操作映射。

Lets take example of your classes:

让我们举例说明你的课程:

Project
  - ProjectId (PK)
  - Name
  - ProjectContents

ContentType
  - ContentTypeId (PK)
  - Name
  - ProjectContents

ProjectContentTypeMapping
  - ProjectId (PK)
  - ContentTypeId (PK)
  - OtherRelevantColumn

where ProjectContents is of type ProjectContentTypeMapping

其中ProjectContents的类型为ProjectContentTypeMapping

so whenever you add a Project with Certain ContentType, you would be doing this:

因此,无论何时添加具有某些ContentType的项目,您都会这样做:

Project prj = new Project();
//fill out scalar properties
ProjectContentTypeMapping pctm = new ProjectContentTypeMapping();
pctm.ContentTypeId = 1; //or whatever you want, or selected from UI

prj.ProjectContents = new ProjectContentTypeMapping();
prj.ProjectContents.Add(pctm);

dataContext.Projects.Add(prj);

Now in case of editing (adding ContentTypes) to an existing project, you won't do prj.ProjectContents = new ... rather, you would do it only when it is null i,e,

现在在编辑(添加ContentTypes)到现有项目的情况下,你不会做prj.ProjectContents = new ...相反,你只会在它为null时执行它,e,e,

if(prj.ProjectContents==null)
   prj.ProjectContents = new ProjectContentTypeMapping();

also, one very very important thing, since now your ProjectContentTypeMapping is no longer a mapping table, so, deleting a Project would give you an error, if its id is being present in ProjectContentTypeMapping table; you will have to remove them manually i.e

另外,一个非常重要的事情,因为现在你的ProjectContentTypeMapping不再是一个映射表,因此,如果Project的内容出现在ProjectContentTypeMapping表中,删除一个Project会给你一个错误;你必须手动删除它们,即

foreach(var pctm in prj.ProjectContents.ToList())
{
   prj.ProjectContents.Remove(pctm);
   datacontext.ProjectContentTypeMappings.Remove(pctm);
}
datacontext.Remove(prj);
datacontext.SaveChanges();