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

标签 vb.net asp.net-mvc-4 entity-framework-5

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

相关文章:

c# - @Html.RadioButtonFor 默认为未选中

c# - EF 自定义结果集映射

c# - 在 LINQ 查询中使用 ToString()?

asp.net-mvc-4 - ASP.NET SimpleMembershipProvider 自动迁移

.net - 可以通过名称实例化和调用委托(delegate)吗?

vb.net - 在这种情况下 & 操作在做什么

c# - 如何从 Selenium Driver.PageSource 获取 HtmlAgilityPack.HtmlDocument?

c# - 有效域的正则表达式

c# - 使用 FormCollection 中的数据发出异步 HttpClient 发布请求

c# - Kendo MVC ToDataSourceResult 非常慢,IQueryable 很大