如何在Linq to Sql中插入或更新where子句?

我试图将以下存储过程转换为LinqToSql调用(这是SQL的简化版本):

INSERT INTO [MyTable] ([Name], [Value]) SELECT @name, @value WHERE NOT EXISTS(SELECT [Value] FROM [MyTable] WHERE [Value] = @value) 

DB对要检查的字段没有约束,因此在这种特定情况下,需要手动进行检查。 此外,还有许多项目不断被插入,所以我需要确保当这个特定的插入发生时,没有值字段的欺骗。 我的第一个预感是做以下事情:

 using (TransactionScope scope = new TransactionScope()) { if (Context.MyTables.SingleOrDefault(t => t.Value == in.Value) != null) { MyLinqModels.MyTable t = new MyLinqModels.MyTable() { Name = in.Name, Value = in.Value }; // Do some stuff in the transaction scope.Complete(); } } 

这是我第一次遇到这种情况,所以我想确保以正确的方式进行。 这看起来是否正确,或者任何人都可以提出一个更好的方法来解决它而不需要两个单独的电话?

编辑:我遇到类似的更新问题:

 UPDATE [AnotherTable] SET [Code] = @code WHERE [ID] = @id AND [Code] IS NULL 

我如何使用Linqtosql进行相同的检查? 我假设我需要做一个get然后设置所有值并提交,但是如果有人在执行更新时将[Code]更新为null以外的其他内容会怎么样?

与插入相同的问题……

如果数据库中没有唯一约束,则在TransactionScope中包装它实际上不会阻止冲突。 它只保证了这笔交易的primefaces性。

在开始更新之前,完全有可能并且可能在高容量场景中让两个同时发生的事务通过第一次null检查(这只是一次读取)。 在数据库中强制执行唯一性约束非常重要 – 如果你不能在这里做到这一点,那么你就可以为你完成工作了。

老实说,根据您的要求,我建议改为使用存储过程。 Linq to SQL是一个很棒的工具,但它无法完成SQL所能做的一切 ; 这似乎是你需要比L2S真正能给你更多控制的情况之一。

如果这是一个意外情况(即表示错误), UNIQUE约束就足够了。

没有直接的方法可以通过LINQ-to-SQL来实现,因此您的TransactionScope (或传入的连接上的SqlTransaction )是一种可行的机制。 另一个可能是替代触发器或执行INSERT的存储过程。

你拥有的可能是最简单的; 看它是否足够快(它有一个额外的往返)并坚持下去?

我不相信LINQ-to-SQL可行,但更好的选择是使用Any()而不是SingleOrDefault()

 using (TransactionScope scope = new TransactionScope()) { if (!Context.MyTables.Any(t => t.Value == in.Value)) { MyLinqModels.MyTable t = new MyLinqModels.MyTable() { Name = in.Name, Value = in.Value }; // Do some stuff in the transaction scope.Complete(); } } 

我相信Any()在SQL中使用EXISTS关键字,它选择布尔值而不是该行中所有列的完整内容。

Aaron建议使用存储过程可能更简单 – 您也可以将其连接到您的datacontext。