C# 实体框架在一次插入多行时忽略重复的主键值
我正在使用LINQ和实体框架在SQLServer2012数据库中插入一些数据 插入数据的数据库表有一个主键,我一次插入大约1000条记录 也就是说,出于性能原因,我检索1000行数据集,并一次性保存这1000行数据 现在的问题是,我可能偶尔会得到这1000行中任何一行的重复值,当这种情况发生时,所有行都不会保存在数据库中 是否有任何方法可以在插入所有其他非重复行时,默默地忽略这一行而不插入它 我也尝试在每次插入之前查询数据库,但是这样做的性能代价太高了 是否有任何方法可以在插入所有其他非重复行时,默默地忽略这一行而不插入它 如果可以在SQL Server中重新创建索引,则可以忽略重复项。插入后,在不忽略重复的情况下重新创建索引,因为没有重复会更快C# 实体框架在一次插入多行时忽略重复的主键值,c#,sql-server,database,linq,entity-framework,C#,Sql Server,Database,Linq,Entity Framework,我正在使用LINQ和实体框架在SQLServer2012数据库中插入一些数据 插入数据的数据库表有一个主键,我一次插入大约1000条记录 也就是说,出于性能原因,我检索1000行数据集,并一次性保存这1000行数据 现在的问题是,我可能偶尔会得到这1000行中任何一行的重复值,当这种情况发生时,所有行都不会保存在数据库中 是否有任何方法可以在插入所有其他非重复行时,默默地忽略这一行而不插入它 我也尝试在每次插入之前查询数据库,但是这样做的性能代价太高了 是否有任何方法可以在插入所有其他非重复行时
CREATE TABLE [dbo].[YourTable](
[id] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
我建议您在insert语句之前做一些额外的处理,不需要任何代码,我将尝试用伪代码向您展示
ICollection<record> myRecords = Service.GetMyRecords();
//your processing logic before the insert
ICollection<record> recordsToInsert =Service.BusinessLogic(myRecords);
foreach(var record in recordsToInsert)
{
if(myRecords.Contains(record )
{
recordsToInsert.Remove(record);
}
}
ICollection myRecords=Service.GetMyRecords();
//插入之前的处理逻辑
ICollection recordsToInsert=Service.BusinessLogic(myRecords);
foreach(recordsToInsert中的var记录)
{
if(myRecords.Contains)(记录)
{
记录插入。删除(记录);
}
}
这将确保recordsToInsert集合中没有将使数据库跳闸的记录。这还将为您保存一条尝试的insert语句,因为它不会尝试并失败。首先执行一个查询,检查是否存在任何新记录,如下所示:
var checks = records.Select(r => r.Id).ToArray();
if (!context.Records.Any(r => check.Contains(r.Id))
{
// do the insert
}
在第一次检查之后,您可以对检查进行细化,以找出1000条记录中的哪一条是罪魁祸首。因此,愉快的场景总是非常快的。只有在找到重复记录时,过程才会更慢
您不能告诉EF在运行一个事务时悄悄忽略一个数据库异常。Sql表本身不能有重复的主键,因此实体框架对此无能为力,不应回避约束,而应尊重约束,将用户操作排队到一个作业中,该作业可以在用户继续移动时并行完成还有很多方法可以在不忽略数据完整性的情况下处理此问题。问题是该表有1.5亿条以上的记录,检查是否存在任何记录是一个耗时的过程。然后我建议更改数据库上的设置以正确处理此问题,因为这似乎是运行时成本最低的解决方案;user3123649建议有一种方法可以做到这一点。