如何只更新那些循环更新的行?

时间:2019-08-20 15:24:30

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

我有一个应用程序,该应用程序每1秒钟不断更新,因此我需要相应地更新数据库。

我有下面的getOrg函数,该函数从API端点获取数据并将其插入数据库,但是在插入之前,它会检查哈希是否存在重复项,直到此为止它确实运行良好。但是问题是,如果发生某些变化,将会有新的哈希,并且作为新哈希将继续并尝试插入记录,但是由于OrgGuid是我的主键,所以它给了我:

  

SqlException:违反PRIMARY KEY约束

所以我的问题是如何只更新那些已更改的列?

public async Task getOrg()
{
    var request = new HttpRequestMessage(HttpMethod.Get, "organizations");
    var response = await _client_NP.SendAsync(request);
    var json = await response.Content.ReadAsStringAsync();
    OrganizationsClass.OrgsRootObject model = JsonConvert.DeserializeObject<OrganizationsClass.OrgsRootObject>(json);

    foreach (var item in model.resources)
    {
        string tmpmasterhash = HashClass.CreateMD5(item.guid + item.name + item.created_at + item.updated_at);

        if (!_DBcontext.Organizations.Any(o => o.Orghash == tmpmasterhash))
        {
            var Orgs = new Organizations
            {
                OrgGuid = Guid.Parse(item.guid),
                Name = item.name,
                CreatedAt = item.created_at,
                UpdatedAt = item.updated_at,
                Orghash = tmpmasterhash,
                Timestamp = DateTime.Now,
                Foundation = 3
            };
            _DBcontext.Organizations.Add(Orgs);
        }
    }

    await _DBcontext.SaveChangesAsync();
}

2 个答案:

答案 0 :(得分:2)

首先为给定的Guid检索组织,如果存在,则对其进行更新。如果不存在,请添加

var g = Guid.Parse(item.guid);
var x = _DBcontext.Organizations.FirstOrDefault(o => o.OrgGuid == g);
if(x == null)
  _DBcontext.Organizations.Add(new Organizations
                {
                    OrgGuid = g,
                    Name = item.name,
                    CreatedAt = item.created_at,
                    UpdatedAt = item.updated_at,
                    Orghash = tmpmasterhash,
                    Timestamp = DateTime.Now,
                    Foundation = 3
                });
else{
  x.Name = item.name;
  .... //whatever else you want to update
}

await _DBcontext.SaveChangesAsync();

PS;如果哈希改变了,基于它进行重复数据删除不是一个好主意;根据定义,您的ID不会改变,不要打扰您的哈希-使用您用于PK的Guid吗?


根据我的评论,哈希实际上仅对了解是否应运行数据库更新有用,但老实说,它可能没有用。我希望如果将属性更新为它们已经具有的相同值,EF将不会费心保存对象,因此计算哈希值会浪费时间,但是您可能会这样做:

var g = Guid.Parse(item.guid);
var x = _DBcontext.Organizations.FirstOrDefault(o => o.OrgGuid == g);
if(x == null){
  _DBcontext.Organizations.Add(new Organizations
                {
                    OrgGuid = g,
                    Name = item.name,
                    CreatedAt = item.created_at,
                    UpdatedAt = item.updated_at,
                    Orghash = tmpmasterhash,
                    Timestamp = DateTime.Now,
                    Foundation = 3
                });
  await _DBcontext.SaveChangesAsync();
} else if(tmpmasterhash  != x.Orghash) {
  x.Name = item.name;
  .... //whatever else you want to update
  await _DBcontext.SaveChangesAsync();
}

答案 1 :(得分:1)

附加

将记录附加到上下文。这是一种乐观的行为:实体框架希望该记录存在,并且仅观察使用此附加记录的其他记录。对附加记录所做的任何修改都不会传递到数据库。

阅读:https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state

原始答案:https://pt.stackoverflow.com/a/38195/14630