实体框架 - 如果尚未持久化,则避免重复子代

时间:2011-07-22 18:19:56

标签: c# entity-framework orm

实际上我使用DbContext,但我也只是用ObjectContext测试它。

// Engine 1
Engine engine = new Engine();
Manufacturer manufacturer = new Manufacturer();

engine.Manufacturer = manufacturer;

// Engine 2
engine = new Engine();
engine.Manufacturer = manufacturer // Engine 2 has the same manufacturer like Engine 1

context.SaveChanges();

我使用标识列(int),其中生成新ID。在调试模式下,我看到引擎的ID是“0”。好吧,如果我在Engine 1块之后立即实现了context.SaveChanges,那么新的制造商将被保存到DB。使用EntityKey或任何检查,我可以毫无问题地将新制造商引用到引擎2。但是没有立即的SaveChanges(),同一制造商的两个条目将被保存到DB(上面的代码)。 EF无法像普通物体一样在内部引用吗?正如您所见,制造商是同一个对象,所以我想知道是否可以在不预先保存子/制造商的情况下获得成功的插入。

编辑:我认为我发现了问题

MachineEntities context = new MachineEntities();
        context.Configuration.AutoDetectChangesEnabled = true;

        // Engine 1
        Engine engine1 = new Engine();
        engine1.Name = "engine1";

        Manufacturer manufacturer = new Manufacturer();
        manufacturer.Name = "manufacturer1";

        engine1.Manufacturer = manufacturer;

        // Engine 2
        Engine engine2 = new Engine();
        engine2.Name = "engine2";

        manufacturer = new Manufacturer();
        manufacturer.Name = "manufacturer1";

        engine2.Manufacturer = manufacturer;


        // Add Engine 1

        if (context.Manufacturers.Any(m => m.Name == engine1.Manufacturer.Name))
        {
            // The manufacturer's name is identical, so use the one in the context instead the assigned one.
            engine1.Manufacturer = context.Manufacturers.Single(m => m.Name == engine1.Manufacturer.Name);
        }
        else
        {
            // The manufacturer is not known, add it to the context
            context.Set<Manufacturer>().Add(engine1.Manufacturer);
        }

        // Add Engine 2


        if (context.Manufacturers.Any(m => m.Name == engine1.Manufacturer.Name))
        {
            // The manufacturer's name is identical, so use the one in the context instead the assigned one.
            engine2.Manufacturer = context.Manufacturers.Single(m => m.Name == engine2.Manufacturer.Name);
        }
        else
        {
            context.Manufacturers.Add(engine2.Manufacturer);
        }

        context.SaveChanges();

        context.Dispose();

“任何”或任何比较都不会给我任何结果。它只给我那些已经存在于DB中的实体,而不是新添加的实体。所以这是重复的。正如我在调试器中看到的那样忽略了本地的那些,而“结果视图”中的那个是执行命令的那个。所以新添加的实体位于“Manufacturers.Local”。

1 个答案:

答案 0 :(得分:1)

我刚刚尝试了以下内容:

var a1 = new Activity{WorkflowId = 1, Title = "test"};
var a2 = new Activity{WorkflowId = 1, Title = "test2"};
var d = new WorkflowDisplay{WorkflowId = 1, Title = "Test"};
a1.WorkflowDisplay = d;
a2.WorkflowDisplay = d;
// Any of the next three lines can be commented out, but if
// they are all commented, nothing happens.
AddToWorkflowDisplays(d);
AddToActivities(a1);
AddToActivities(a2);
SaveChanges();

...我只看到添加了一个WorkflowDisplay。所以我很确定这与您的具体实现有关。您是否覆盖了任何实体的GetHashCodeEquals方法,或者对自动生成的代码进行了类似的自定义?