1

我是 Entity Framework 的新手,我已经为导航对象的问题苦苦挣扎了一天多。我怀疑我正在尝试以一种不合适的方式与 EF 合作。我正在使用框架 4 和 EF v4。

我创建了一个示例模型来大致演示我遇到的问题。我的实际系统是一个 ASP.Net 应用程序。我们有一个页面,允许用户创建“DisplayBoards”并向其中添加一个或多个预先存在的“Bays”。在保存之前,用户有机会调整显示托架的顺序。这记录在链接记录上。

因为链接记录显示在列表中(按顺序),所以在选择每个托架时,我一直在创建一个新的链接对象,添加托架,然后使用链接对象列表绑定到网格。这工作正常。

尝试将链接对象添加到新的 DisplayBoard 并保存所有内容时,最终回发时会出现问题。

在新链接对象上调用“AddObject”时会引发异常:“EntityKey 属性只能在属性的当前值为 null 时设置。”

这是基本的表结构:

DisplayBoard
DisplayBoardID(PK,身份)
DisplayBoardName

BoardBayLink
LinkID (PK, identity)
DisplayBoardID (FK)
BayID (FK)
DisplayOrder (int)

Bay
BayID (PK, 身份)
BayName

这是一些示例代码。这是一个使用三个上下文的控制台应用程序,但这是为了模拟 ASP.Net 应用程序上的回发。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EF_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Entity Framework Issue");
            Console.WriteLine("Setting FK outside of context");
            Console.WriteLine();

            DisplayBoard newBoard = null;
            Bay existingBayOne = null;
            Bay existingBayTwo = null;
            List<BoardBayLink> newLinksList = new List<BoardBayLink>();

            /* In this example there are two contexts.
             * This is to simulate an ASP.Net scenario...
             *      First, a new DisplayBoard is created at UI level.
             *      A Bay is searched for and selected via callback or postback.
             *      A new BoardBayLink is created at UI level and the Bay record is added.
             *      Once user is happy, final postback to save.
             *      
             * This is why there are two contexts here in a console app.
             */

            // New display board created
            newBoard = new DisplayBoard() { DisplayBoardName = "My new display board" };

            // User searches for and selects a Bay (via postback)
            using (EntityFrameworkTestEntities context = new EntityFrameworkTestEntities())
            {
                existingBayOne = context.Bays.Where(bay => bay.BayID == 1).FirstOrDefault();
            }
            // Now that the user has selected a bay, create a new BoardBayLink object and add the Bay to it.
            newLinksList.Add(new BoardBayLink() { Bay = existingBayOne, DisplayOrder = 1 });


            // User searches for and selects another Bay (via postback)
            using (EntityFrameworkTestEntities context2 = new EntityFrameworkTestEntities())
            {
                existingBayTwo = context2.Bays.Where(bay => bay.BayID == 2).FirstOrDefault();
            }
            // Now that the user has selected a second bay, create a new BoardBayLink object and add the Bay to it.
            newLinksList.Add(new BoardBayLink() { Bay = existingBayTwo, DisplayOrder = 2 });


            // Show the new board with it's newly added Bays in the UI
            // User has not yet clicked save.
            Console.Write("Display board: ");
            Console.WriteLine(newBoard.DisplayBoardName);

            Console.WriteLine("Bays: ");
            foreach (BoardBayLink link in newLinksList.OrderBy(link => link.DisplayOrder))
            {
                Console.WriteLine(link.Bay.BayName);
            }


            Console.WriteLine("Press any key to continue with save....");
            Console.ReadKey();

            // Now use a third context (because we're pretending this is a postback)
            using (EntityFrameworkTestEntities context3 = new EntityFrameworkTestEntities())
            {
                context3.DisplayBoards.AddObject(newBoard); // Add the new board to the context

                foreach (BoardBayLink link in newLinksList)
                {
                    context3.BoardBayLinks.AddObject(link);
                    newBoard.BoardBayLinks.Add(link);
                }

                context3.SaveChanges();
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

如何将托架添加到链接记录并避免我看到的错误消息?

谢谢

4

1 回答 1

0

您无法再次添加链接,您已经在上下文之外创建了关系

newLinksList.Add(new BoardBayLink() { Bay = ... };

尝试再次添加它newBoard.BoardBayLinks.Add(link)会导致错误。

要添加新链接,您只需在第三个上下文中执行以下操作:

using (EntityFrameworkTestEntities context3 = new EntityFrameworkTestEntities())
{
    context3.DisplayBoards.Add(newBoard);
    context3.SaveChanges();
}

调用该Add()方法将标记EntityState图中所有实例的Added,依次为每个实例创建一个新的数据库记录。

于 2013-05-01T07:23:12.180 回答