2010-04-05 2 views
0

Я столкнулся с интересной ошибкой со следующим запросом LiNQ с использованием LiNQPad и при использовании Subsonic 3.0.xw/ActiveRecord в моем проекте и хотел поделиться ошибкой и разрешением для всех, кто работает в нем.Ошибка SQLiteException и SQLite около "(": синтаксическая ошибка с Subsonic ActiveRecord

оператор LINQ ниже предназначен для записей группы в коллекции tblSystemsValues ​​в их соответствующей системе, а затем извлечь систему с наибольшим ID.

from ksf in KeySafetyFunction where ksf.Unit == 2 && ksf.Condition_ID == 1 
    join sys in tblSystems on ksf.ID equals sys.KeySafetyFunction 
    join xval in (from t in tblSystemsValues 
group t by t.tblSystems_ID into groupedT 
    select new 
    { 
    sysId = groupedT.Key, 
    MaxID = groupedT.Max(g=>g.ID), 
    MaxText = groupedT.First(gt2 => gt2.ID == 
       groupedT.Max(g=>g.ID)).TextValue, 
    MaxChecked = groupedT.First(gt2 => gt2.ID == 
       groupedT.Max(g=>g.ID)).Checked 
    }) on sys.ID equals xval.sysId 
select new {KSFDesc=ksf.Description, sys.Description, xval.MaxText, xval.MaxChecked} 

о себе, подзапрос для группировки в groupedT отлично работает и запрос для соответствия KeySafetyFunctions с их система в tblSystems также отлично работает сама по себе.

Однако при попытке запустить заполненный запрос в LINQPad или в моем проекте я продолжал работать в SQLiteException SQLite Error Near "("

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

В конце концов я разделил запрос на три отдельные части, прежде чем понял, что это было ленивое выполнение запросов, которые меня убивали. Затем стало ясно, что добавление спецификатора .ToList() после запроса myProtectedSystem ниже было ключом к тому, чтобы избежать ленивого исполнения после объединения и оптимизации запроса и получения моих результатов, несмотря на проблемы, с которыми я столкнулся с драйвером SQLite.

// determine the max Text/Checked values for each system in tblSystemsValue 
var myProtectedValue = from t in tblSystemsValue.All() 
     group t by t.tblSystems_ID into groupedT 
      select new { 
      sysId = groupedT.Key, 
      MaxID = groupedT.Max(g => g.ID), 
      MaxText = groupedT.First(gt2 => gt2.ID ==groupedT.Max(g => g.ID)).TextValue, 
      MaxChecked = groupedT.First(gt2 => gt2.ID ==groupedT.Max(g => g.ID)).Checked}; 
// get the system description information and filter by Unit/Condition ID 
var myProtectedSystem = (from ksf in KeySafetyFunction.All() 
     where ksf.Unit == 2 && ksf.Condition_ID == 1 
      join sys in tblSystem.All() on ksf.ID equals sys.KeySafetyFunction 
      select new {KSFDesc = ksf.Description, sys.Description, sys.ID}).ToList(); 
// finally join everything together AFTER forcing execution with .ToList() 
var joined = from protectedSys in myProtectedSystem 
     join protectedVal in myProtectedValue on protectedSys.ID equals protectedVal.sysId 
      select new {protectedSys.KSFDesc, protectedSys.Description, protectedVal.MaxChecked, protectedVal.MaxText}; 
    // print the gratifying debug results 
    foreach(var protectedItem in joined) 
     { 
      System.Diagnostics.Debug.WriteLine(protectedItem.Description + ", " + protectedItem.KSFDesc + ", " + protectedItem.MaxText + ", " + protectedItem.MaxChecked); 
     } 

ответ

0

Избегайте ленивые вычисления, заставляя раннее исполнение с .ToList() на один из компонентов конечного запроса. Результаты пойдут в память, поэтому постарайтесь убедиться, что вы выбираете небольшой набор данных и не заставляете неограниченный запрос или гигантский запрос в списке.