C# 使用 EF 的多对多关系插入操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19130983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:10:33  来源:igfitidea点击:

Insert operation with many-to-many relationship using EF

c#asp.net-mvcentity-frameworkmany-to-many

提问by hendrixchord

I've two model classes:

我有两个模型类:

public class Candidate
{
  public int Id { get; set; }
  public string Name { get; set; }
  public ICollection<Job> Jobs { get; set; }
}

public class Job
{
  public int Id { get; set; }
  public string Name { get; set; }
  public ICollection<Candidate> Candidates { get; set; }
}

My DbContext name is JobsContext.

我的 DbContext 名称是 JobsContext。

The above code generates me 3 tables Candidates, Jobs & CandidatesJobs(autogenerated by EF)

上面的代码为我生成了 3 个表 Candidates、Jobs 和 CandidatesJobs(由 EF 自动生成)

Now I've records in Jobs table : Id = 1, Name = "Sales" : Id = 2, Name = "Engineer".

现在我在 Jobs 表中记录了:Id = 1, Name = "Sales" : Id = 2, Name = "Engineer"。

I want to associate a new Candidate which I'll be inserting into Candidates table with the 2 records from Jobs table.

我想将我将插入到 Candidates 表中的新 Candidate 与 Jobs 表中的 2 条记录相关联。

Before inserting the Candidate I know the Id's of the Jobs table & I don't wish to make a call to the database to get more details from Jobs table.

在插入 Candidate 之前,我知道 Jobs 表的 Id 并且我不想调用数据库以从 Jobs 表中获取更多详细信息。

How do I do this using Entity Framework 5?

如何使用实体框架 5 执行此操作?

采纳答案by Henk Mollema

How about this?

这个怎么样?

Job salesJob; // already fetched from db
Job engineerJob; // already fetched from db

Candidate candidate = new Candidate();
candidate.Name = "John Doe";
candidate.Jobs = new List<Job>(); // you could also do this in the constructor of Candidate
candidate.Jobs.Add(salesJob);
candidate.Jobs.Add(engineerJob);

context.SaveChanges();

This only works if you already fetched the jobs from the database within the same instance of the DbContext, else EF will think that the jobs are 'new' and tries to insert them. If you only have the ids, you could try the following:

这仅适用于您已经在DbContext. 如果您只有 id,您可以尝试以下操作:

var salesJob = new Job { Id = salesJobId };
var engineerJob = new Job { Id = engineerJobId };

context.Jobs.Attach(salesJob);
context.Jobs.Attach(engineerJob);

candiate.Jobs.Add(salesJob);
candiate.Jobs.Add(engineerJob);
context.SaveChanges();

回答by cbeckner

There are two options.

有两种选择。

If you are going to have the same context and candidate objects laying around, you can simply add the existing candidate objects to the job. For example: Create your candidates and save them to the database:

如果您要放置相同的上下文和候选对象,您只需将现有的候选对象添加到作业中即可。例如: 创建您的候选人并将其保存到数据库中:

JobsContext context = new JobsContext();
var candidate1 = new Candidate() { Name = "John Smith" }; //id 1
var candidate2 = new Candidate() { Name = "Jane Smith" }; //id 2
var candidate3 = new Candidate() { Name = "John Doe" }; //id 3
context.Candidates.Add(candidate1);
context.Candidates.Add(candidate2);
context.Candidates.Add(candidate3);
context.SaveChanges();

Then, create your job:

然后,创建您的工作:

var job = new Job() { Name = "Good Job" }; //id 1

Finally, add your candidates to the new jobvariable, add the job to the context and save changes.

最后,将您的候选人添加到新job变量中,将工作添加到上下文中并保存更改。

job.Candidates.Add(candidate1);
job.Candidates.Add(candidate2);
context.Jobs.Add(job);
context.SaveChanges();

OR

或者

If you are using a DIFFERENT context from the one you created the candidates with, then you can create a new candidate object and attach it to the context prior to adding it to the job.

如果您使用的上下文与创建候选对象的上下文不同,那么您可以创建一个新的候选对象并将其附加到上下文,然后再将其添加到作业中。

//different context from above example
JobsContext newContext = new JobsContext();
//this can be a new or existing job, using the job from the example above here
var existingJob = newContext.Jobs.FirstOrDefault(j => j.Id == 1);

Create our candidate object by setting onlythe ID

通过设置ID 来创建我们的候选对象

var existingCandidate3 = new Candidate() { Id = 3 };

Attach the object to the new context. Note: if the context from the example above is still around, it will not let you do this since it is already tracking the candidate.

将对象附加到新上下文。 注意:如果上面例子中的上下文仍然存在,它不会让你这样做,因为它已经在跟踪候选人。

newContext.Candidates.Attach(existingCandidate3);

Set the state to Unchanged since we don't want to create a new candidate, just use the existing one.

将状态设置为 Unchanged 因为我们不想创建新的候选者,只需使用现有的候选者。

newContext.Entry(existingCandidate3).State = System.Data.EntityState.Unchanged;

Add it and save the changes.

添加它并保存更改。

existingJob.Candidates.Add(existingCandidate3);
newContext.SaveChanges();

Done!

完毕!

回答by HackTheDj

A very simple solution is to create a VIEW of the xref table exactly as the table (view_tablename_raw). Then update that view in EF as an entity without foreign keys. From their use context.view_tablename_raw.Add(...) and it will work seamlessly.

一个非常简单的解决方案是创建与表 (view_tablename_raw) 完全相同的外部参照表的 VIEW。然后将 EF 中的该视图更新为没有外键的实体。从他们的使用上下文.view_tablename_raw.Add(...) 它将无缝地工作。