gpt4 book ai didi

vb.net - Entity Framework 多对多关系值未保存在数据库中

转载 作者:行者123 更新时间:2023-12-05 05:27:16 24 4
gpt4 key购买 nike

我已经使用 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com