Entity Framework - 保存外键引用新记录

3
我有一个在Entity Framework中保存数据的问题。
我已经写好了一个函数,覆盖了我的dbContext的saveChanges函数,因为我用它来设置一些审计数据和做其他工作。在某种情况下,我遇到了麻烦。
我需要为每个新记录插入一些记录到另一个表中,并引用一个外键与新记录相关联。如果只有一条新记录,一切都正常。但如果有两条或更多记录,我会遇到错误。
我使用循环来遍历所有新记录,如下所示:
var addedAuditedEntities = ChangeTracker.Entries()
    .Where(p => p.State == EntityState.Added)
    .Select(p => p.Entity);

foreach (var added in addedAuditedEntities)
{
    .....
}

我写下了我的尝试。

1)这种方式在第二个新记录处出现错误,说“TabAssVeicoliTerminali”标签页中已经有唯一数据(它是一个拥有IDTER-IDTEV对上独特索引的表格),我认为是因为它插入所有IDTEV = 0的临时记录。

else if (added.GetType() == typeof(TabTessereVeicoli))
{
    TabTessereVeicoli i = (TabTessereVeicoli)added;
    i.DATA_INS = now;
    i.USER_INS = mdlImpostazioni.p.UserName;
    var listaterV = new List<TabAssVeicoliTerminali>();
    foreach (var ter in MainWindow.dbContext.TabTerminali) 
    {
        var tt = new TabAssVeicoliTerminali();
        tt.MODIFICATO = true;
        tt.ABILITATO = true;
        tt.IDTER = ter.ID;
        tt.IDTEV = i.ID;
        tt.DATA_INS = now;
        tt.USER_INS = mdlImpostazioni.p.UserName;
        listaterV.Add(tt);
    }
    MainWindow.dbContext.BulkInsert(listaterV);
}

2) 我之前尝试过保存,试图设置新记录的ID(它是自动增量ID),并在IDTEV外键中使用“!= 0”的某些内容。但是,它保存了所有内容,包括其他新记录。因此,它正确地将fk保存在其他表中,但仅适用于第一个新记录:

else if (added.GetType() == typeof(TabTessereVeicoli))
{
    TabTessereVeicoli i = (TabTessereVeicoli)added;
    i.DATA_INS = now;
    i.USER_INS = mdlImpostazioni.p.UserName;
    var listaterV = new List<TabAssVeicoliTerminali>();
    base.SaveChanges();
    foreach (var ter in MainWindow.dbContext.TabTerminali) 
    {
        var tt = new TabAssVeicoliTerminali();
        tt.MODIFICATO = true;
        tt.ABILITATO = true;
        tt.IDTER = ter.ID;
        tt.IDTEV = i.ID;
        tt.DATA_INS = now;
        tt.USER_INS = mdlImpostazioni.p.UserName;
        listaterV.Add(tt);
    }
    MainWindow.dbContext.BulkInsert(listaterV);
}

3) 我也尝试过不使用BulkInsert,但结果相同。

我该如何达成我的目标呢?


你检查过这一对吗:ter.ID 和 i.ID?如果 i.ID 为0,你将不会遇到唯一约束问题,因为 ter.ID 将给你不同的值。 - macpak
@BenRobinson你写道:“……除非将它们添加到父记录的导航属性集合中……”。你是什么意思?如果我这样做,i.ID会不等于0吗?怎么做? - Piero Alberto
1
我不知道你的实体具体是什么样子的,但总体来说,你可以使用 ParentEntity.Children.Add(childEntity); 的方式来实现你的一对多关系,其中 ParentEntity.Children 是你的导航属性。 - Ben Robinson
@BenRobinson 这样做会有什么变化?我可以在批量插入中使用它吗? - Piero Alberto
@BenRobinson 好的,现在它可以工作了,但是如何与批量插入一起使用呢?根据您的提示,我已经对批量部分进行了注释,但是我仍需要它,因为可以在同一时间插入大量数据。 - Piero Alberto
显示剩余8条评论
1个回答

0

从Ben Robinson在这个问题的评论中提供的提示开始,我找到了一个解决方案。

它可以工作,但仍然不是“完美的解决方案”,因为为了做到这一点,我不得不注释掉批量插入的部分,所以在有大量新记录时速度会变慢。

无论如何,我在问题中发布的代码现在是:

else if (added.GetType() == typeof(TabTessereVeicoli))
{
    TabTessereVeicoli i = (TabTessereVeicoli)added;
    i.DATA_INS = now;
    i.USER_INS = mdlImpostazioni.p.UserName;
    var listaterV = new List<TabAssVeicoliTerminali>();
    foreach (var ter in MainWindow.dbContext.TabTerminali) 
    {
        var tt = new TabAssVeicoliTerminali();

        tt.MODIFICATO = true;
        tt.ABILITATO = true;
        tt.IDTER = ter.ID;
        tt.IDTEV = i.ID;
        tt.DATA_INS = now;
        tt.USER_INS = mdlImpostazioni.p.UserName;
        //listaterV.Add(tt);
        i.TabAssVeicoliTerminali.Add(tt);
    }
    //MainWindow.dbContext.BulkInsert(listaterV);
}

如果您知道如何使用bulkInsert达到我的目标,请告诉我!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接