C# 实体框架核心使用唯一检查添加多行
我将在循环中向数据库添加多个新行,然后保存更改。但我有一个跨3列的唯一索引accross,所以我需要首先检查它们是否不存在以防止异常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[
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查询不会拾取新添加到内存中的行。