使用主键和备用复合键更新实体

时间:2016-10-19 18:58:53

标签: sql sql-server entity-framework asp.net-core entity-framework-core

我每天都会将一系列指标快照数据上传到我的数据库中。我接受输入并检查以确定它是否已经存在于数据库中,如果不是,我将其添加。每条记录使用一个由三列组成的复合键,并且还有一个主键。

我已经尝试添加逻辑,以便我可以选择强制更新已存在于数据库中的记录,此外还要添加那些尚不存在的记录。我遇到了一个错误,虽然阻止了我,说已经存在一个跟踪指定键的对象。

  

实体类型的实例' MembershipSnapshot'无法跟踪   因为此类型的另一个具有相同密钥的实例已经存在   被跟踪。添加新实体时,对于大多数键类型都是唯一的   如果没有设置密钥,则将创建临时密钥值(即,如果密钥   属性被指定为其类型的默认值)。如果你是   明确设置新实体的关键值,确保不这样做   与现有实体或为其他实体生成的临时值发生冲突   新实体。附加现有实体时,请确保只有一个实体   具有给定键值的实体实例附加到上下文。

这是我的代码片段。

    // Get the composite keys from the supplied list
    var snapshotKeys = snapshots.Select(s => new { s.MembershipYear, s.DataDate, s.Aggregate }).ToArray();
    // Find which records already exist in the database, pulling their composite keys
    var snapshotsInDb = platformContext.MembershipSnapshots.Where(s => snapshotKeys.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate }))
                                       .Select(s => new { s.MembershipYear, s.DataDate, s.Aggregate }).ToArray();
    // And filter them out, so we remain with the ones that don't yet exist
    var addSnapshots = snapshots.Where(s => !snapshotsInDb.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate }))
        .ToList();
    // Update the ones that already exist
    var updateSnapshots = snapshots.Where(s => snapshotsInDb.Contains(new { s.MembershipYear, s.DataDate, s.Aggregate }))
        .ToList();
    platformContext.MembershipSnapshots.AddRange(addSnapshots);
    platformContext.MembershipSnapshots.UpdateRange(updateSnapshots);
    platformContext.SaveChanges();

如何完成此任务?

我没有令人信服的理由说明为什么我有一个自动增加的主键,除了可能在内部给SQL带来的任何性能问题?

编辑:我目前解决这个问题的方法是删除我的代理密钥,我根本不会使用任何东西。尽管如此,知道一个解决方法而不必删除它会很好,因为代理密钥在将来会派上用场。

0 个答案:

没有答案