使用EF插入具有多对多关系的操作

时间:2013-10-02 06:16:00

标签: c# asp.net-mvc entity-framework many-to-many

我有两个模型类:

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; }
}

我的DbContext名称是JobsContext。

上面的代码生成了3个表候选人,工作&amp; CandidatesJobs(由EF自动生成)

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

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

在插入候选人之前,我知道了乔布斯表格中的Id&amp;我不希望调用数据库来从Jobs表中获取更多细节。

如何使用Entity Framework 5执行此操作?

3 个答案:

答案 0 :(得分:18)

这个怎么样?

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();

仅当您已在DbContext的同一实例中从数据库中提取作业时才有效,否则EF会认为作业是“新”并尝试插入它们。如果您只有ids,可以尝试以下方法:

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();

答案 1 :(得分:6)

有两种选择。

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

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();

然后,创建你的工作:

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

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

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

如果您使用的是创建候选对象的不同上下文,则可以在将其添加到作业之前创建新的候选对象并将其附加到上下文。

//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);

通过设置 ID

来创建候选对象
var existingCandidate3 = new Candidate() { Id = 3 };

将对象附加到新上下文。 注意:如果上述示例中的上下文仍然存在,则不会允许您执行此操作,因为它已经在跟踪候选项。

newContext.Candidates.Attach(existingCandidate3);

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

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

添加并保存更改。

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

完成!

答案 2 :(得分:0)

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