我已经使用 Code First 和 Entity Framework 5 建立了多对多关系。连接表已创建,但字段数据未保存到数据库。
工作人员已成功添加到项目对象中,并且 db.SaveChanges() 方法执行无误,但是当再次调用/Project/Edit/x 操作的 GET 请求时,工作人员列表属性为空。
如何实现这项工作,以便在通过 POST“保存”后连接的 Worker 数据与 GET 请求中的 Project 对象一起保留和检索?
Controller :ProjectController.vb
POST:/项目/创建/x
For i As Integer = LBound(strWorkerIds) To UBound(strWorkerIds)
Dim workerId As Integer
If Integer.TryParse(Trim(strWorkerIds(i)), workerId) Then
Dim worker As Worker = db.Workers.Find(workerId)
If Not worker Is Nothing Then
project.Workers.Add(worker)
End If
End If
Next
If ModelState.IsValid Then
db.Projects.Add(project)
db.SaveChanges() ' The project is saved along with the correct project.Workers list
Return RedirectToAction("Index", "Home")
End If
发布:/项目/编辑/x
For i As Integer = LBound(strWorkerIds) To UBound(strWorkerIds)
Dim workerId As Integer
If Integer.TryParse(Trim(strWorkerIds(i)), workerId) Then
Dim worker As Worker = db.Workers.Find(workerId)
If Not worker Is Nothing Then
project.Workers.Add(worker)
End If
End If
Next
If ModelState.IsValid Then
db.Entry(project).State = EntityState.Modified
db.SaveChanges() 'The changes to project.Workers list are NOT being saved?
Return RedirectToAction("Index", "Home")
End If
模型:Project.vb
Public Class Project
Public Sub New()
Me.Workers = New List(Of Worker)()
End Sub
Public Property ProjectID As Integer
'other properties...
Public Overridable Property Workers As ICollection(Of Worker)
End Class
模型:Worker.vb
Public Class Worker
Public Sub New()
Me.Projects = New List(Of Project)()
End Sub
Public Property WorkerID As Integer
'other properties...
Public Overridable Property Projects As ICollection(Of Project)
End Class
数据库上下文:ProjectLogContext.vb
Imports System.Data.Entity
Imports System.Data.Entity.ModelConfiguration.Conventions
Public Class ProjectLogContext
Inherits DbContext
Public Property Projects As DbSet(Of Project)
Public Property Workers As DbSet(Of Worker)
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
MyBase.OnModelCreating(modelBuilder)
modelBuilder.Conventions.Remove(Of PluralizingTableNameConvention)()
modelBuilder.Entity(Of Worker)().HasMany(Function(w) w.Projects) _
.WithMany(Function(p) p.Workers) _
.Map(Function(x) x.MapLeftKey("WorkerID").MapRightKey("ProjectID") _
.ToTable("WorkerProject"))
End Sub
End Class
最佳答案
将父实体的状态设置为 Modified
不会对多对多关联中的关系产生任何影响。要实现正确的更新,您必须从数据库加载当前实体图(包括其子项的父项),然后添加一个子项(如果其 ID 在您的 ID 列表中)或删除 child 的 ID 不在 ID 列表中。 EF 的更改跟踪将跟踪加载图的那些修改,并生成必要的 INSERT 和 DELETE 语句来更新链接表。在您的 Edit POST 操作(在 C# 中)中它可能看起来像这样:
var projectInDb = db.Projects.Include(p => p.Workers)
.SingleOrDefault(p => p.ProjectID == project.ProjectID);
if (projectInDb != null)
{
// Convert string list to integer list
var workerIds = new List<int>();
foreach (string strWorkerId in strWorkerIds)
{
int workerId;
if (int.TryParse(strWorkerId.Trim(), out workerId))
workerIds.Add(workerId);
}
// Update scalar properties of the project
db.Entry(projectInDb).CurrentValues.SetValues(project);
// Remove workers
foreach (var workerInDb in projectInDb.Workers.ToList())
{
if (!workerIds.Contains(workerInDb.WorkerID))
projectInDb.Workers.Remove(workerInDb);
}
// Add workers
foreach (int workerId in workerIds)
{
if (!projectInDb.Workers.Any(w => w.WorkerID == workerId))
{
var workerInDb = db.Workers.Find(workerId);
if (workerInDb != null)
projectInDb.Workers.Add(workerInDb);
}
}
db.SaveChanges();
}
关于vb.net - Entity Framework 多对多关系值未保存在数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20875094/