DbContext 无法保存多个条目

DbContext failing to save multiple entries

我试图通过 foreach 循环获取存储在数据库中的对象列表,这是我当前的代码:

foreach (var i in ruleset)
{
    var currentRule = Rule;
    currentRule.OriginIP = i[0];
    currentRule.DestinationIP = i[1];
    currentRule.Protocol = (Protocol)Enum.Parse(typeof(Models.Protocol), i[2]);
    currentRule.Ports = i[3];
    _context.Rules.Add(currentRule);
    Console.WriteLine(_context.ChangeTracker.DebugView.LongView);
    Console.WriteLine(currentRule.RuleID);

}
_context.SaveChanges();

出于某种原因,这实际上只存储了列表中的最后一个对象,我在循环之外使用了 SaveChanges(),因为我认为这会提高性能。

当我 运行 时,我得到以下信息:

rule {RuleID: -2147482647} Added
  RuleID: -2147482647 PK Temporary
  CreationDate: '26/01/2021 14:16:10'
  DestinationIP: '10.232.20.20'
  Enabled: 'False'
  OriginIP: '192.168.10.10'
  Ports: '80, 443'
  Protocol: 'TCP'

0

rule {RuleID: -2147482647} Added
  RuleID: -2147482647 PK Temporary
  CreationDate: '26/01/2021 14:16:10'
  DestinationIP: '10.232.20.21' Originally '10.232.20.20'
  Enabled: 'False'
  OriginIP: '192.168.10.11' Originally '192.168.10.10'
  Ports: '80, 444' Originally '80, 443'
  Protocol: 'TCP'

看到 ChangeTracker 显示每个条目的更改,我尝试将 SaveChanges() 放入循环中,但随后第一个条目被存储,第二个错误输出,因为它尝试使用与它相同的条目 ID刚刚保存:

rule {RuleID: -2147482647} Added
  RuleID: -2147482647 PK Temporary
  CreationDate: '26/01/2021 14:25:40'
  DestinationIP: '10.232.20.20'
  Enabled: 'False'
  OriginIP: '192.168.10.10'
  Ports: '80, 443'
  Protocol: 'TCP'

62

rule {RuleID: 62} Added
  RuleID: 62 PK
  CreationDate: '26/01/2021 14:25:40'
  DestinationIP: '10.232.20.21' Originally '10.232.20.20'
  Enabled: 'False'
  OriginIP: '192.168.10.11' Originally '192.168.10.10'
  Ports: '80, 444' Originally '80, 443'
  Protocol: 'TCP'

我知道我一定做错了什么,但我找不到什么!

您一遍又一遍地添加相同的规则。试试像

foreach (var i in ruleset)
{
    var currentRule = new Rule();
    currentRule.OriginIP = i[0];
    currentRule.DestinationIP = i[1];
    currentRule.Protocol = (Protocol)Enum.Parse(typeof(Models.Protocol), i[2]);
    currentRule.Ports = i[3];
    _context.Rules.Add(currentRule);
}
_context.SaveChanges();
var currentRule = Rule;

_context.Rules.Add(currentRule);

您一遍又一遍地添加相同的 Rule 对象。

当您向 EF 添加内容时,它会跟踪该对象。这就是 EF 知道实体何时更新的方式。 EF 无法多次跟踪同一个内存中对象并假装它们不同。

第一次添加您的实体。
第二次,EF 意识到这是和以前一样的对象,因此没有添加任何新的东西 - 它已经在跟踪这个对象了。

确保添加 new 个对象,例如:

var currentRule = new Rule();

// set some values

_context.Rules.Add(currentRule);