.net - 如何使用 Linq-to-SQL 只插入新记录?

标签 .net linq linq-to-sql insert

我必须定期在 SQL Server 数据库中插入一些数据。但是我读取数据的提要重复了之前插入的一些数据。当我使用 Linq-to-SQL 插入数据库时​​,某些数据会重复,或者会引发主键冲突异常,具体取决于主键。

如何插入数据而不重复、不出现异常?我不想用 try-catch 来避免异常,因为一旦引发异常,其余数据就不会插入。

更新我还找到了自己的解决方案:我编写了一个重复条目删除存储过程,该过程在InsertAllOnSubmit + SubmitChanges之后立即运行

最佳答案

您所要做的就是创建类的新实例,然后在表上调用 InsertOnSumbit():

var foo = new MyFoo { Name = "foo1" };
var dc = new MyDataContext();
dc.Foos.InsertOnSubmit(foo);
dc.SubmitChanges();

您需要确定的另一件事是如何增加 ID 列。一般来说,我总是确保在 ID 列上使用 IDENTITY(1,1) 设置。这是在 LINQ 实体的 id 列上声明的,如下所示:

[Column(AutoSync = AutoSync.OnInsert, IsPrimaryKey = true, IsDbGenerated = true)]
public Int32 Id { get; set; }

为了避免重复,您真正需要的是我们在我的商店中所说的“附加”功能。恕我直言,这可以通过存储过程轻松完成 - 我们甚至有一个用于它的模板:

USE [<Database_Name, sysobject, Database_Name>]
GO

CREATE PROCEDURE [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>__append]
(
    @id INT OUTPUT,
    @<Key_Param, sysobject, Key_Param> <Key_Param_Type, sysobject, VARCHAR(50)>
)
AS
BEGIN

        SELECT @id = [id] FROM [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>s] (NOLOCK) WHERE [<Key_Param, sysobject, Key_Param>] = @<Key_Param, sysobject, Key_Param>

IF @id IS NULL  
BEGIN       
    INSERT INTO [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>s] ([<Key_Param, sysobject, Key_Param>]) 
    OUTPUT INSERTED.[id] INTO @inserted_ids
    VALUES (@<Key_Param, sysobject, Key_Param>)

    SELECT TOP 1 @id = [id] FROM @inserted_ids;
END
ELSE
BEGIN
    UPDATE [<Schema, sysobject, dbo>].[<Table_Name, sysobject, Table_Name>s]
    SET
        [<Key_Param, sysobject, Key_Param>] = @<Key_Param, sysobject, Key_Param>
    WHERE [id] = @id
END
END
GO

不过,可以在 linq 中执行此操作,只需查询现有 ID 的列表(或您要关闭的任何列):

var dc = new MyDataContext();
var existingFoos = dc.Foos.ToList();
var newFoos = new List<Foo>();
foreach(var bar in whateverYoureIterating) {
// logic to add to newFoos 
}
var foosToInsert = newFoos.Where(newFoo => !existingFoos.Any(existingFoo => newFoo.Id == existingFoo.Id));

dc.Foos.InsertAllOnSubmit(foosToInsert);
dc.SubmitChanges();
// use the next line if you plan on re-using existingFoos. If that's the case I'd wrap  dc.SubmitChanges() in a try-catch as well.
existingFoos.AddRange(foosToInsert);

关于.net - 如何使用 Linq-to-SQL 只插入新记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/725708/

相关文章:

.net - Entity Framework 和事务范围在处理事务范围后不会恢复隔离级别

c# - double[] 集合到字符串

sql - .NET .ToList 函数太慢了

.net - 未生成 LINQ to SQL 关联

c# - 重定向到 POST HttpWebRequest

C# 使用 FileSystemWatcher 跟踪文件夹连接

c# - 我可以用 throw 移除空捕获吗?

c# - Entity Framework Core LINQ 创建查询时遇到问题(选择案例存在)

sql - 如何将此 SQL 查询转换为 LINQ 或 Lambda 表达式?

sql - Linq2Sql 中的 System.DateTime 和 Sql datetime2(使用 sqlmetal)