Я довольно хорошо разбираюсь в LINQ, но не в SQL. Я понимаю, что курсоры ужасны и не должны использоваться. Я хорошо знаю синтаксис SQL, но пытаюсь понять, как преобразовать этот запрос и обновить его до SQL из Linq. Я не знаю, как пройти Foreach SQL без использования курсоров, и я немного не понимаю, что делать дальше ...

Как видите, я просматриваю всю таблицу из примерно 150 000 строк, Linqpad просто не может обработать обновление, поэтому мне нужно, чтобы это было сделано в SQL.

Я перебираю каждую запись в первой таблице, затем нахожу Guid в двух других таблицах, извлекаю эти данные из этих двух таблиц и обновляю оригинал.

Кто-нибудь может помочь? Спасибо всем!!!!!

  CS_Code.UtopiaDataContext db = new CS_Code.UtopiaDataContext();
        var getFirst = (from xx in db.Utopia_Province_Data_Captured_Gens
                        select xx);
        foreach (var item in getFirst)
        {
            var updateItem = (from xx in db.Utopia_Province_Infos
                              where xx.Province_ID == item.Province_ID
                              select xx).FirstOrDefault();
            if (updateItem != null)
            {
                item.Owner_User_ID = updateItem.User_ID;
                item.Last_Login_For_Province = updateItem.Last_Login_Province;
                item.Date_Time_User_ID_Linked = updateItem.Date_Time_Added;
                item.Added_By_User_ID = updateItem.Added_By_User_ID;
            }
            var updateItema = (from xx in db.Utopia_Province_Identifiers
                               where xx.Province_ID == item.Province_ID
                               select xx).FirstOrDefault();
            if (updateItema != null)
            {
                item.Owner_Kingdom_ID = updateItema.Owner_Kingdom_ID;
                item.Kingdom_ID = updateItema.Kingdom_ID;
                item.Province_Name = updateItema.Province_Name;
                item.Kingdom_Island = updateItema.Kingdom_Island;
                item.Kingdom_Location = updateItema.Kingdom_Location;
            }
        }
        db.SubmitChanges();
1
SpoiledTechie.com 29 Дек 2009 в 10:49
Ха-ха, Утопия, я много играл в это, я был тем, кто написал Utopia Simulator и Utopia Formatter версии 1 и 2 :)
 – 
Aviad P.
29 Дек 2009 в 10:52
2005 Sql ... Что-нибудь еще? Авиад, я человек, работающий над UtopiaPimp ...
 – 
SpoiledTechie.com
29 Дек 2009 в 10:55

2 ответа

Лучший ответ

Если я правильно понимаю, вы пытаетесь выполнить запрос на обновление. Во-первых, если вы можете использовать предложение Джона Скита и вам удобнее работать с LINQ, сделайте это. Эквивалент SQL должен быть примерно таким:

UPDATE info
SET
  gens.Owner_User_ID = item.User_ID
  gens.Last_Login_For_Province = item.Last_Login_Province
FROM
  Utopia_Province_Infos as info 
  INNER JOIN Utopia_Province_Data_Captured_Gens as gens 
  ON info.Province_ID = gens.Province_ID

Этот запрос объединяет две таблицы, делая каждую строку «длинной», содержащей обе таблицы. Он переходит к обновлению некоторых полей в каждой строке.

Вы устанавливаете остальные поля Utopia_Province_Data_Captured_Gens так же, как и с User_ID. Вы делаете то же самое, заменяя Utopia_Province_Infos на Utopia_Province_Identifiers для второй таблицы в вашем коде.

Примечание. Я не принимал во внимание использование вами FirstOrDefault. Вы можете установить значение по умолчанию непосредственно в Utopia_Province_Infos или просто обновить значения, которые не были установлены (используя предложение where). Насчет «Первого» - есть ли в Utopia_Province_Infos несколько строк с одинаковым идентификатором Province_ID? Почему ты идешь первым?

3
Asaf R 29 Дек 2009 в 12:24
Как мне просмотреть каждую строку данных и обновить каждую строку? Действительно ли этот запрос делает это?
 – 
SpoiledTechie.com
29 Дек 2009 в 19:19

Ну, в первую очередь вы должны выполнить соединение - в настоящее время вы выполняете два дополнительных запроса для каждой строки таблицы, что невероятно неэффективно. Вот пример соединения:

var results = from xx in db.Utopia_Province_Data_Captured_Gens
              join yy in db.Utopia_Province_Infos 
                       on xx.Province_ID equals yy.Province_ID
              select new { item = xx, updateItem = yy };
foreach (var result in results)
{
    result.item.Owner_User_ID = result.updateItem.User_ID;
    result.item.Last_Login_For_Province = result.updateItem.Last_Login_Province;
    result.item.Date_Time_User_ID_Linked = result.updateItem.Date_Time_Added;
    result.item.Added_By_User_ID = result.updateItem.Added_By_User_ID;
}

// Ditto for second query

Обратите внимание, что это обновит все элементы с соответствующими Province_ID, а не только первый, но я предполагаю, что в любом случае это первичные ключи, так что это не будет проблемой.

РЕДАКТИРОВАТЬ: Я должен отметить, что решение Асафа является предпочтительным с точки зрения эффективности. Нет смысла возвращать все данные клиенту, если база данных может сделать все сама.

1
Jon Skeet 29 Дек 2009 в 13:28
Я могу только представить, что Linqpad все еще не может справиться с этим и выходит из строя ... Ошибки обычно возникают из-за исключения нехватки памяти ...
 – 
SpoiledTechie.com
29 Дек 2009 в 10:57
Спасибо, Джон, даже несмотря на то, что ты дал мне правильный ответ, я бы хотел, чтобы он не вышел из строя. Кажется, он продолжал вызывать исключение нехватки памяти, потому что Linqpad продолжал выплевывать инструкцию SQL после каждой операции ...
 – 
SpoiledTechie.com
29 Дек 2009 в 22:37
@Scott: Странно, что он выдает оператор SQL после каждой операции ... что за оператор?
 – 
Jon Skeet
29 Дек 2009 в 23:21