Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Linq合并来自两个源的数据的更好方法_C#_Sql_Linq - Fatal编程技术网

C# 使用Linq合并来自两个源的数据的更好方法

C# 使用Linq合并来自两个源的数据的更好方法,c#,sql,linq,C#,Sql,Linq,我有一些C#/Linq代码用于将excel文件中的数据合并到数据库中,这需要更好的性能 有 1.从excel文件读取的列表:列表新闻核心列表 2.一个名为Scores、主键peopleId和testDate 我需要将列表中的数据合并到表中,如果有任何重复数据,请更新它 我目前的解决办法是: 1) 使用此LINQ表达式查找重复数据: var dupliData = from newScore in newScoreList from oldScore in db.Score

我有一些C#/Linq代码用于将excel文件中的数据合并到数据库中,这需要更好的性能


1.从excel文件读取的列表:
列表新闻核心列表

2.一个名为
Scores
、主键
peopleId
testDate

我需要将列表中的数据合并到表中,如果有任何重复数据,请更新它

我目前的解决办法是:

1) 使用此LINQ表达式查找重复数据:

var dupliData =  
    from newScore in newScoreList  
    from oldScore in db.Scores  
    where newScore.peopleId == oldScore.peopleId && newScore.testDate == oldScore.testDate  
    select oldScore;  
2) 删除重复的数据

db.Scores.DeleteAllOnSubmit(dupliData); 
3) 从列表中插入新数据

db.Scores.InsertAllOnSubmit(newScoreList);

有谁能给我一个更好的解决方案吗?

一般来说,我真的很讨厌存储过程,但这可能是一个使用存储过程的完美案例。我的TSQL已经生锈了,但这应该会给出一个想法

CREATE PROCEDURE dbo.InsertOrUpdateScore
(
    @id as Int,
    @date as DateTime,
    @result as varchar(20)
)
AS

if not exists(SELECT id FROM Scores WHERE id = @id AND date = @date)
begin
   INSERT INTO Scores (id, date, result) values (@id, @date, @result)
end
else
begin
   UPDATE Scores
   SET result = @result
   WHERE id = @id AND date = @date
end
GO 
现在,在LINQ服务器浏览器中,选择Score实体,并更改其插入和更新行为,以使用刚才创建的存储过程。确保访问数据库的用户具有存储过程的执行权限

这应该比您的版本执行得快一些。您正在用IN子句交换索引上的N个选项,这可能会更快。但是,IN子句的结果集不会通过网络传输回客户端,这可以节省大量时间

准确地描述您的方法在实现之前需要多长时间,这样您就可以判断这是否真的更快

我不确定这是否是在你的应用程序中创建一个分数的唯一方法,但是你可能需要考虑插入一个没有ID的记录的情况。你需要修改sPRC以允许<代码> @ ID>代码>为<代码> null <代码>,并适当地处理插入。 那么应该是:


如果您使用的是SQL 2008,则可以使用Merge命令

您必须删除并重新创建它们吗?或者,您可以只更新现有的行,这应该会产生更好的性能。您是否查看过SQL Profiler中的某些查询,是否存在异常数量的查询?我们谈论的记录有多少,性能问题在哪里?选择?删除?插页?因为使用Linq的大量插入无论如何都会给您带来性能-在这种情况下,您应该看看SqlBulkCopy@TheScrum Meister,你说得对,我的代码一次又一次地扫描列表浪费了太多时间,这可以在一次扫描中完成。@Albin我以前不知道SQL Profiler,但我会试试的,谢谢!谢谢你的回答和详细解释。我不熟悉存储过程,按照您的逻辑我重写了代码,使用哈希表包含数据并执行查询。现在演出好多了。但我相信使用存储过程的解决方案必须提供更好的性能。您不希望使用存储过程。您也可以使用内联sql。@usr,我不喜欢应用程序中的内联sql,除非绝对需要。如果这是一个简单的选择;大概但这涉及到SQL逻辑,在所有意义上都是过程/方法。您可以在c#或存储过程中编写该方法。关键是,无论您是插入还是更新,在指定的需求下,这两个都需要相同的逻辑。谢谢@Pleun,尽管我实际上使用的是sql 2000,但这个命令很有趣
db.Scores.InsertAllOnSubmit(newScoreList);