在Ado.net C中动态构建Where子句#

我将在给定时间内接收大约1000条记录,我必须确定它们是现有记录还是新记录。

如果它们存在,我必须更新记录,如果是新的,则只需插入它们。 我不知道他们中的任何一个是否存在,或者它们是否都存在。

我认为最好对数据库进行一次查询并尝试查找数据库中是否存在任何查询并将其存储在内存中并在内存中检查该集合并检查它。

最初我被告知我1场将足以确定唯一性。 所以我想我可以在数据库中对1个字段做一个大的in子句,但现在我发现情况并非如此,我需要使用3个字段来确定记录是存在还是现在。

这基本上是一个和条款

select * from where columnA = "1" and ColumnB = "2" and ColumnC = "3" 

我怎样才能在C#ado.net中正确地识别它?

我猜我需要有一些超级where子句?

 select * from where (columnA = "1" and ColumnB = "2" and ColumnC = "3") or (columnA = "4" and ColumnB = "5" and ColumnC = "6") or [....998 more conditional clauses) 

如果可能的话,我愿意接受更好的想法。 我仍然认为一次性完成它比做1000次单独查询更好。

我只能帮助您为您的请求编写查询

  var recordCount = 1000; var query = "SELECT * FROM TableName WHERE"; for (var i = 1; i < recordCount - 2; i += 3) { query += " (columnA = " + i + " and ColumnB = " + (i + 1) + " and ColumnC = " + (i + 2) + ") or "; } 

我觉得写这个答案有点傻,因为我认为你应该能够将其他post的完整答案放在一起 – 但这并不是我想到的任何一个问题的完全重复。

Stackoverflow中已经有问题和答案处理这个问题 – 但是在我的搜索中我只找到了非线程安全的答案,而且大多数都是使用merge

我可以向您推荐不同的问题和答案,例如我在c#中向数据库添加多个参数化变量的答案,您可以在c#中查看如何使用表值参数,以及Aaron Bertrand对使用if条件的答案插入SQL Server ,你可以在其中看到如何创建一个安全的upsert – 但是我没有找到任何完全覆盖这个的答案 – 所以你去:

首先,您需要在数据库中创建用户定义的表类型:

 CERATE TYPE MyTableType AS TABLE ( Column1 int NOT NULL, Column2 int NOT NULL, Column3 int NOT NULL, -- rest of the columns in your table goes here PRIMARY KEY (Column1, Column2, Column3) ) 

然后,您创建存储过程:

 CREATE stp_UpsertMyTable ( @MyTableType dbo.MyTableType readonly -- table valued parameters must be readonly ) AS SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION; UPDATE t SET t.column4 = tvp.column4, t.column5 = tvp.column5 -- and so on for all columns that are not part of the key FROM dbo.MyTable AS t INNER JOIN @MyTableType AS tvp ON t.Column1 = tvp.Column1 AND t.Column2 = tvp.Column2 AND t.Column3 = tvp.Column3; -- Note:  should be replaced with the actual columns in the table INSERT dbo.MyTable() SELECT  FROM @MyTableType AS tvp WHERE NOT EXISTS ( SELECT 1 FROM dbo.MyTable t WHERE t.Column1 = tvp.Column1 AND t.Column2 = tvp.Column2 AND t.Column3 = tvp.Column3 ); COMMIT TRANSACTION; GO 

然后,c#部分很简单:

 DataTable dt = new DataTable(); dt.Columns.Add("Column1", typeof(int)); dt.Columns.Add("Column2", typeof(int)); dt.Columns.Add("Column3", typeof(int)); dt.Columns.Add("Column4", typeof(string)); dt.Columns.Add("Column5", typeof(string)); // Fill your data table here using (var con = new SqlConnection("ConnectionString")) { using(var cmd = new SqlCommand("stp_UpsertMyTable", con)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@MyTable", SqlDbType.Structured).Value = dt; con.Open(); cmd.ExecuteNonQuery(); } } 

现在,您可以使用表值参数进行完整且安全的upsert,在c#和sql server之间只进行一次往返。