使用EF插入具有多对多关系的操作
我有两个模型类:
public class Candidate { public int Id { get; set; } public string Name { get; set; } public ICollection Jobs { get; set; } } public class Job { public int Id { get; set; } public string Name { get; set; } public ICollection Candidates { get; set; } }
我的DbContext名称是JobsContext。
上面的代码生成了3个表候选人,工作和候选人工作(由EF自动生成)
现在我在Jobs表中记录:Id = 1,Name =“Sales”:Id = 2,Name =“Engineer”。
我想将一个新的Candidate与Jobs表中的2个记录关联到Candidates表中。
在插入候选人之前,我知道了Jobs表的Id,我不想调用数据库来从Jobs表中获取更多细节。
如何使用Entity Framework 5执行此操作?
这个怎么样?
Job salesJob; // already fetched from db Job engineerJob; // already fetched from db Candidate candidate = new Candidate(); candidate.Name = "John Doe"; candidate.Jobs = new List(); // you could also do this in the constructor of Candidate candidate.Jobs.Add(salesJob); candidate.Jobs.Add(engineerJob); context.SaveChanges();
这仅在您已在DbContext
的同一实例中从数据库中提取作业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();
有两种选择。
如果要使用相同的上下文和候选对象,则只需将现有候选对象添加到作业中即可。 例如:创建候选人并将其保存到数据库:
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();
完成!
一个非常简单的解决方案是创建外部参照表的VIEW,与表(view_tablename_raw)完全相同。 然后在EF中将该视图更新为没有外键的实体。 从他们的使用上下文 .view_tablename_raw.Add(…),它将无缝地工作。