简体   繁体   English

如何处理多个新添加的实体,这些实体依赖于具有外键约束的每个水獭 - EF6

[英]How to deal with multiple newly Added Entities that depend on each otter with a Foreign key constraint - EF6

I had a bit of difficulties with getting the right title for this problem so I hope my explanation below will make it a bit clearer.我在为这个问题找到正确的标题时遇到了一些困难,所以我希望我下面的解释能让它更清楚一点。

I am using EntityFramework 6 and I am doing multiple inserts within a function.我正在使用EntityFramework 6 ,并且正在 function 中进行多次插入。

There are 3 different tables which get updated / inserted: table EntityMethod , EntityRoom and EntityRoomMethod .有 3 个不同的表需要更新/插入:表EntityMethodEntityRoomEntityRoomMethod The table EntityRoomMethod has a foreign key relationship with the table EntityMethod .EntityMethod与表EntityRoomMethod具有foreign key关系。

In some cases, a EntityMethod row is missing and this is newly created by adding the object with entity framework:在某些情况下,缺少EntityMethod行,这是通过添加带有实体框架的 object 新创建的:

if (mn == null)
{
    mn = new Method
    {
        ElementId = floorProgram.ElementId,
        ActionId = m.ActionId,
        ElementCount = m.ElementCount,
        ColorId = m.ColorId,
        IsBase = m.IsBase,
        IsHccp = m.IsHccp,
        TimeNorm = m.TimeNorm,
        Frequency5Id = m.Frequency5Id,
        MaterialId = m.MaterialId,
        ProductId = m.ProductId,
        MethodTypeId = m.MethodTypeId,
    };
}

In another part of code the Method foreign key (MethodId) of the EntityRoomMethod table is being set:在另一部分代码中,设置了EntityRoomMethod表的Method foreign key (MethodId)

roomMethodObject.RightId = mn.Id; 

RightId is in this case the relationship with the EntityMethod table. RightId在这种情况下是与EntityMethod表的关系。

On a later point the other 2 table objects ( EntityRoom and EntityRoomMethod ) are also added ( DBSet.Add ) using EF.稍后,还使用 EF 添加了其他 2 个表对象( EntityRoomEntityRoomMethod )( DBSet.Add )。

The problem however is, that when the EntityMethod is newly added, it gets the Id value of 0 , because SaveChanges() is not yet executed.然而问题是,当添加EntityMethod时,它的Id值为0 ,因为SaveChanges()尚未执行。 The foreign key reference in the EntityRoomMethod is therefor also being set to 0 . EntityRoomMethod中的外键引用也因此设置为0

When the function returns to the caller, the SaveChanges() is being executed and all 3 objects (representing the 3 tables) are being saved.当 function 返回调用者时,正在执行SaveChanges()并且正在保存所有 3 个对象(代表 3 个表)。 This however will generate a FK error (because Id 0 does not exist obviously).然而,这会产生一个 FK 错误(因为 Id 0 显然不存在)。

I tried to fix this by calling SaveChanges() after Adding the new Method (so directly in the function).我试图通过在添加新方法后调用SaveChanges()来解决这个问题(直接在函数中)。 This however will cause some other problems.然而,这将导致一些其他问题。 In the end I have gotten multiple errors but I assume it all has to do with the same thing, the errors were the following:最后我得到了多个错误,但我认为这一切都与同一件事有关,错误如下:

  1. Unable to determine the principal end of the 'Solution.Data.RoomMethod_Method' relationship.无法确定“Solution.Data.RoomMethod_Method”关系的主体端。 Multiple added entities may have the same primary key.多个添加的实体可能具有相同的主键。
  2. The property 'RightId' is part of the object's key information and cannot be modified.属性“RightId”是对象的关键信息的一部分,不能修改。
  3. Conflicting changes to the role x of the relationship y have been detected已检测到关系 y 的角色 x 的冲突更改

So now the actual question: Is there an (easy) way to call SaveChanges() after all 3 entities have been added with EF but also handling the FK errors?所以现在的实际问题是:在所有 3 个实体都添加了 EF 并且还处理 FK 错误之后,是否有一种(简单的)方法来调用SaveChanges() Does this mean I have to generate the Id's myself?这是否意味着我必须自己生成 ID? Or was the first approach better (Calling SaveChanges directly after adding the EntityMethod object).或者第一种方法更好(在添加EntityMethod对象后直接调用SaveChanges )。

For now I have some not-nice-looking solution with doing a direct INSERT statement after adding a new EntityMethod (using Dapper ).现在我有一些看起来不太好看的解决方案,在添加新的EntityMethod (使用Dapper )之后执行直接INSERT语句。 This kind-of works but I assume there is a better way wherein I can just use EF6.这种工作,但我认为有更好的方法,我可以只使用 EF6。

PS calling SaveChanges() after adding the EntityMethod was basically the same by doing it with Dapper , however this generated some other errors while using Dapper it didn't generate those errors. PS 在添加EntityMethod后调用SaveChanges()与使用Dapper执行此操作基本相同,但是在使用Dapper时这会产生一些其他错误,但不会产生这些错误。

You can wrap several SaveChanges within a transaction, and EF (or probably SQL) will generate the required ids at each point, allowing you to reference them later on.您可以在事务中包装多个SaveChanges ,EF(或者可能是 SQL)将在每个点生成所需的 id,以便您稍后引用它们。

using(var transaction = _context.Database.BeginTransaction())
{
   var p1 = new Something { Name = "Fred" };
   _context.SaveChanges();

   var a2 = new Dependency { SomethingId = p1.Id }; <-- p1.Id now has an Id value
   _context.SaveChanges();

   var b3 = new OtherDependency { DependencyId = a2.Id };  <-- a2.Id now has an Id value
   _context.SaveChanges();

  transaction.Commit(); <-- All 3 changes are fully committed to the db at this point.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM