将Linq代码块转换为SQL

时间:2017-10-20 18:51:19

标签: c# sql-server linq

主要目标是将适当的数据从一个表迁移到另一个表,并且由于我的技能在sql中并不明显,我使用linq和foreach语句编写逻辑来完成所需的操作。但是,需要一个sql脚本才能在不同的环境中运行,所以我开始将我之前写的内容翻译成sql,并且我的sql思维过程在GroupBy和循环海岸上被打破了。

以下是我的尝试,实际上会返回准确的数据结果

SELECT BookID FROM (SELECT bt.BookID, pt.PaperID, ppt.PropID
FROM BooksTable AS bt
JOIN PapersTable AS pt
ON bt.BookID = pt.BookID
JOIN PapersPropertiesTable AS ppt
ON pt.PaperID = ppt.PaperID) AS ResultSet
GROUP BY BookID

以下是我遇到问题的代码

foreach (var i in ResultSetGroupedByBookID)
{
    var resultToMigrate= i.DistinctBy(j => j.PropID).ToList();

    foreach (var j in resultToMigrate)
    {
        db.InsertPropsProcedure(j.BookID, j.PropID);
    }
}

主要挑战

  • GroupingBy返回包含其他列的内部结果集
  • 循环遍历内部结果集,DistinctBy PropID并返回另一个
  • 循环遍历新集,调用插入过程并传递参数

更新

我选择了Stepen的答案,因为它的简单;然而,我遇到了我需要在返回第三列时不同于多列的情况,所以我必须执行以下modifications

INSERT INTO Table2(BookID, PropID, PropValue)
SELECT DISTINCT bt.BookID, ppt.PropID, MAX(ppt.PropValue) AS PropValue
FROM BooksTable AS bt
JOIN PapersTable AS pt ON bt.BookID = pt.BookID
JOIN PapersPropertiesTable AS ppt ON pt.PaperID = ppt.PaperID
GROUP BY bt.BookID, ppt.PropertyID
ORDER BY bt.BookID

3 个答案:

答案 0 :(得分:2)

如果你知道SQL&想把它翻译成LINQ 或者你知道LINQ&想把它翻译成SQL

最佳工具是LinqPad

答案 1 :(得分:1)

我不明白你想要做什么,但你的SQL查询可以编写如下:

  SELECT DISTINCT bt.BookID
  FROM BooksTable AS bt
  JOIN PapersTable AS pt ON bt.BookID = pt.BookID
  JOIN PapersPropertiesTable AS ppt ON pt.PaperID = ppt.PaperID;
  • 无需内部查询。
  • 不需要分组。
  • 只需使用DISTINCT

您需要使用INSERT INTO SELECT将此查询的结果插入另一个表中:

  INSERT INTO Table2(BookID,PropID)
  SELECT DISTINCT bt.BookID, ppt.PropID
  FROM BooksTable AS bt
  JOIN PapersTable AS pt ON bt.BookID = pt.BookID
  JOIN PapersPropertiesTable AS ppt ON pt.PaperID = ppt.PaperID

答案 2 :(得分:1)

阅读你的问题和代码并从代码中推断出一点点,我的理解是你要检索一个带有相关纸质属性的BookIds列表,然后为每个执行一个存储过程。使用仅SQL方法而不是让C#编排调用来实现此目的的一种方法是使用游标代替LINQ查询的结果。这是一个例子:

DECLARE migrate_cursor CURSOR
FOR
SELECT DISTINCT bt.BookID, ppt.PropID
FROM BooksTable AS bt
  INNER JOIN PapersTable AS pt
    ON bt.BookID = pt.BookID
  INNER JOIN PapersPropertiesTable AS ppt
    ON pt.PaperID = ppt.PaperID;

OPEN migrate_cursor;

FETCH NEXT FROM migrate_cursor  
INTO @bookId, @propId;  

WHILE @@FETCH_STATUS = 0  
BEGIN  
   EXECUTE my_insert_props_procedure @bookId, @propId

   FETCH NEXT FROM migrate_cursor  
   INTO @bookId, @propId;  
END;

CLOSE migrate_cursor;  
DEALLOCATE migrate_cursor;  

现在,如果这是一个很大的结果集,你会想要考虑诸如使游标仅向前和只读以及避免锁定之类的事情,但是这可以得到一般的想法,而不会使示例过于复杂。您可以在https://docs.microsoft.com/en-us/sql/t-sql/language-elements/cursors-transact-sql

的文档中获取更详细的信息