Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架核心使用唯一检查添加多行_C#_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# 实体框架核心使用唯一检查添加多行

C# 实体框架核心使用唯一检查添加多行,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,我将在循环中向数据库添加多个新行,然后保存更改。但我有一个跨3列的唯一索引accross,所以我需要首先检查它们是否不存在以防止异常 foreach (var row in json["data"]["animals"]) { var newRow = new Animal { Prop1 = row["prop1"].ToString(), Prop2 = row["prop2"].ToString(), Prop3 = row[

我将在循环中向数据库添加多个新行,然后保存更改。但我有一个跨3列的唯一索引accross,所以我需要首先检查它们是否不存在以防止异常

foreach (var row in json["data"]["animals"])
{
    var newRow = new Animal
    {
        Prop1 = row["prop1"].ToString(),
        Prop2 = row["prop2"].ToString(),
        Prop3 = row["prop3"].ToString(),
    }

    if (db.Animals.Where(p => p.Prop1 == newRow.Prop1 && p.Prop2 == newRow.Prop2 && p.Prop3 == newRow.Prop3).FirstOrDefault() == null)
    {
        db.Animals.Add(newRow);
        // db.SaveChanges(); // If I put this here instead, it works (no duplicate exception)
    }
}

db.SaveChanges();  // This throws the duplicate exception
问题是,在
SaveChanges()
之后才能找到我添加到上下文中的行,因此重复检查不起作用。因此,在添加所有行之后,当我执行
SaveChanges()
时,会得到一个重复的异常

foreach (var row in json["data"]["animals"])
{
    var newRow = new Animal
    {
        Prop1 = row["prop1"].ToString(),
        Prop2 = row["prop2"].ToString(),
        Prop3 = row["prop3"].ToString(),
    }

    if (db.Animals.Where(p => p.Prop1 == newRow.Prop1 && p.Prop2 == newRow.Prop2 && p.Prop3 == newRow.Prop3).FirstOrDefault() == null)
    {
        db.Animals.Add(newRow);
        // db.SaveChanges(); // If I put this here instead, it works (no duplicate exception)
    }
}

db.SaveChanges();  // This throws the duplicate exception

添加每行后是否必须保存更改?或者我错过了更好的方法,因为这似乎效率低下/不正确。

您可以覆盖Animal类中的equals方法,并比较字段以避免重复:

public class Animal {

    public int Id { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }


    public override bool Equals(object obj)
    {
      Animal animal = (Animal) obj;

      if (animal == null)
      {
        return false;
      }

      //Compare the values we care about except Id! 
      return this.Prop1 == animal.Prop1
        && this.Prop2 == animal.Prop2
        && this.Prop3 == animal.Prop3;
    }
}
现在,您可以使用Equals override查看任何现有的
动物
对象:

foreach (var row in json["data"]["animals"])
{
   var newRow = new Animal
   {
       Prop1 = row["prop1"].ToString(),
       Prop2 = row["prop2"].ToString(),
       Prop3 = row["prop3"].ToString(),
   }

    var existedAnimal = db.Animals.SingleOrDefault(x => newRow.Equals(x));

    if(existedAnimal == null){
         db.Animals.Add(newRow);
         db.SaveChanges();
    }
    else{
       //You can throw some exception. 
   }
}

您可以重写Animal类中的equals方法,并比较字段以避免重复:

public class Animal {

    public int Id { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }


    public override bool Equals(object obj)
    {
      Animal animal = (Animal) obj;

      if (animal == null)
      {
        return false;
      }

      //Compare the values we care about except Id! 
      return this.Prop1 == animal.Prop1
        && this.Prop2 == animal.Prop2
        && this.Prop3 == animal.Prop3;
    }
}
现在,您可以使用Equals override查看任何现有的
动物
对象:

foreach (var row in json["data"]["animals"])
{
   var newRow = new Animal
   {
       Prop1 = row["prop1"].ToString(),
       Prop2 = row["prop2"].ToString(),
       Prop3 = row["prop3"].ToString(),
   }

    var existedAnimal = db.Animals.SingleOrDefault(x => newRow.Equals(x));

    if(existedAnimal == null){
         db.Animals.Add(newRow);
         db.SaveChanges();
    }
    else{
       //You can throw some exception. 
   }
}

这是因为json数据中有重复的值,首先清除列表中的重复行:

//需要Linq
//使用System.Linq;
//将您的json映射到动物查询表;
var-animals=json[“数据”][“动物”]。选择(行=>新动物{
Prop1=行[“Prop1”]。ToString(),
Prop2=行[“Prop2”]。ToString(),
Prop3=行[“Prop3”]。ToString()
});
//仅选择唯一值
GroupBy(a=>new{a.Prop1,a.Prop2,a.Prop3})。选择(a=>a.First());
//插入的逻辑
foreach(动物中的var newRow)
{
如果(!db.anives.Any(p=>p.Prop1==newRow.Prop1&&p.Prop2==newRow.Prop2&&p.Prop3==newRow.Prop3))
{
db.Animals.Add(纽罗);
//db.SaveChanges();//如果我把它放在这里,它会工作(没有重复的异常)
}
}
db.SaveChanges();//这将引发重复异常

这是因为您的json数据中存在重复值,请首先清除列表中的重复行:

//需要Linq
//使用System.Linq;
//将您的json映射到动物查询表;
var-animals=json[“数据”][“动物”]。选择(行=>新动物{
Prop1=行[“Prop1”]。ToString(),
Prop2=行[“Prop2”]。ToString(),
Prop3=行[“Prop3”]。ToString()
});
//仅选择唯一值
GroupBy(a=>new{a.Prop1,a.Prop2,a.Prop3})。选择(a=>a.First());
//插入的逻辑
foreach(动物中的var newRow)
{
如果(!db.anives.Any(p=>p.Prop1==newRow.Prop1&&p.Prop2==newRow.Prop2&&p.Prop3==newRow.Prop3))
{
db.Animals.Add(纽罗);
//db.SaveChanges();//如果我把它放在这里,它会工作(没有重复的异常)
}
}
db.SaveChanges();//这将引发重复异常

不预先过滤json的一个选项是将新行添加到新集合中,并在db中同时检查其中的重复项,如下所示:

var added = new List<Animal>();
foreach (var row in json["data"]["animals"])
{
    var newRow = new Animal
    {
        Prop1 = row["prop1"].ToString(),
        Prop2 = row["prop2"].ToString(),
        Prop3 = row["prop3"].ToString(),
    }

    if (db.Animals.Where(p => p.Prop1 == newRow.Prop1 && p.Prop2 == newRow.Prop2 && p.Prop3 == newRow.Prop3).FirstOrDefault() != null)
    {
        continue;
    }
    if (added.Where(p => p.Prop1 == newRow.Prop1 && p.Prop2 == newRow.Prop2 && p.Prop3 == newRow.Prop3).FirstOrDefault() != null)
    {
        continue;
    }

    added.Add(newRow);
    db.Animals.Add(newRow);
}

db.SaveChanges();
var added=newlist();
foreach(json[“数据”][“动物”]中的变量行)
{
var newRow=新动物
{
Prop1=行[“Prop1”]。ToString(),
Prop2=行[“Prop2”]。ToString(),
Prop3=行[“Prop3”]。ToString(),
}
if(db.anives.Where(p=>p.Prop1==newRow.Prop1&&p.Prop2==newRow.Prop2&&p.Prop3==newRow.Prop3).FirstOrDefault()!=null)
{
继续;
}
如果(添加了.Where(p=>p.Prop1==newRow.Prop1&&p.Prop2==newRow.Prop2&&p.Prop3==newRow.Prop3).FirstOrDefault()!=null)
{
继续;
}
added.Add(newRow);
db.Animals.Add(纽罗);
}
db.SaveChanges();

不预先过滤json的一个选项是将新行添加到新集合中,并在db中同时检查其中的重复项,如下所示:

var added = new List<Animal>();
foreach (var row in json["data"]["animals"])
{
    var newRow = new Animal
    {
        Prop1 = row["prop1"].ToString(),
        Prop2 = row["prop2"].ToString(),
        Prop3 = row["prop3"].ToString(),
    }

    if (db.Animals.Where(p => p.Prop1 == newRow.Prop1 && p.Prop2 == newRow.Prop2 && p.Prop3 == newRow.Prop3).FirstOrDefault() != null)
    {
        continue;
    }
    if (added.Where(p => p.Prop1 == newRow.Prop1 && p.Prop2 == newRow.Prop2 && p.Prop3 == newRow.Prop3).FirstOrDefault() != null)
    {
        continue;
    }

    added.Add(newRow);
    db.Animals.Add(newRow);
}

db.SaveChanges();
var added=newlist();
foreach(json[“数据”][“动物”]中的变量行)
{
var newRow=新动物
{
Prop1=行[“Prop1”]。ToString(),
Prop2=行[“Prop2”]。ToString(),
Prop3=行[“Prop3”]。ToString(),
}
if(db.anives.Where(p=>p.Prop1==newRow.Prop1&&p.Prop2==newRow.Prop2&&p.Prop3==newRow.Prop3).FirstOrDefault()!=null)
{
继续;
}
如果(添加了.Where(p=>p.Prop1==newRow.Prop1&&p.Prop2==newRow.Prop2&&p.Prop3==newRow.Prop3).FirstOrDefault()!=null)
{
继续;
}
added.Add(newRow);
db.Animals.Add(纽罗);
}
db.SaveChanges();

谢谢你的想法,但这仍然需要在每次添加()后保存数据库更改,我想解决的主要问题是避免这样做。哦,我明白了,然后我增加了上述答案。谢谢你的想法,但这仍然需要在每次添加()后保存数据库更改,我想解决的主要问题是避免这样做。哦,我明白了,那么我要补充上面的答案。我想这样的答案是必须的。db上下文上的Linq查询不会拾取新添加到内存中的行。我想这样的查询是必需的。db上下文上的Linq查询不会拾取新添加到内存中的行。