实体框架多对多关系与额外字段(Database First) [英] Entity Framework many to many relationship with extra field (Database First)

查看:117
本文介绍了实体框架多对多关系与额外字段(Database First)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Project 
- ProjectId(PK)
- Name

ContentType
- ContentTypeId(PK)
- Name

ProjectContentTypeMapping
- ProjectId(PK)
- ContentTypeId(PK)

在这种情况下,一切都很好,我可以访问从ContentTypes项目,反之亦然导航属性。



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



有任何方式,我可以手动配置这两个表之间的映射EF(数据库优先)?或者,我如何表示这一点?我想到可能有一个额外的元数据表与映射表FK,但它看起来hacky给我...



谢谢

解决方案

否,您在实体框架中的映射表中不能有额外列。
因为,有一个额外的列意味着你打算使用它,但映射表不是实体的一部分,因此,实体框架,不再将您的映射表与额外的列作为一个映射表。



我们以你的类为例:

 

code> Project
- ProjectId(PK)
- Name
- ProjectContents

ContentType
- ContentTypeId(PK)
- 名称
- ProjectContents

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

其中ProjectContents类型 ProjectContentTypeMapping



  Project prj = new Project() ; 
//填充标量属性
ProjectContentTypeMapping pctm = new ProjectContentTypeMapping();
pctm.ContentTypeId = 1; //或任何你想要的,或选择从UI

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

dataContext.Projects.Add(prj);

现在在编辑(添加ContentTypes)到现有项目的情况下, c $ c> prj.ProjectContents = new ... 相反,只有当它为空时才会这样做i,e,

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

也是一个非常非常重要的事情,因为现在你的ProjectContentTypeMapping不再是映射表,删除项目会给你一个错误,如果它的ID存在于ProjectContentTypeMapping表中;你必须手动删除它们

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


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:

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.

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.

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...

Thanks

解决方案

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.

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

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

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,

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

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

这篇关于实体框架多对多关系与额外字段(Database First)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆