2014-12-31 5 views
0

Я пытаюсь создать запрос linq, который содержит несколько подзапросов. Запрос я создал кажется правильным (по крайней мере, в синтаксисе), но я не получаю данные отправлены обратно и Скрипач показывает ошибку с этим запросом:C# LInq Subquery Issue

 public IQueryable<vGatekeeperApproval> GetGatekeeperApprovals(string UserName) 
    { 
     SystemsFormsDataContext db = new SystemsFormsDataContext(); 
     IQueryable<vGatekeeperApproval> query; 

     Int32 UserId = GetCurrentUserId(UserName); 
     bool IsGatekeeperApprover = IsCurrentUserGKApprover(UserName); 
     string strSysApproverEmail = GetSystemsApproverEmail(UserName); 

     try 
     { 
      query = (from s in db.vGatekeeperApprovals 
        join r in db.Requests on s.RequestId equals r.Id 
        where (IsGatekeeperApprover == true || s.OverrideApproverId == UserId) 

        && (
        (
        from u in db.Staffs 
        where u.GateKeeperArea == 
         (from c in db.vGK_DIV_USING_CCs 
         where c.SEGMENT_CODE == 
          (from a in db.Attributes 
          where a.AttributeItemId== global_COSTCENTRE && a.FormId==s.Id 
          select a.AttributeValue).FirstOrDefault() 
         select c.PARENT_CODE_L3 
         ).FirstOrDefault() 
        select u.Id 

        ).ToList().Contains(UserId) 

        ) 

        select s 
        ); 


     } 
     catch (Exception ex) 
     { 
      query = (from s in db.vGatekeeperApprovals 
        where s.UserId == 0 
        select s); 

      //LogEvent("ERROR!" + ex.Message, ex.Source); 
     } 

     return query; 
    } 

Любые идеи, что является причиной этой проблемы? Есть ли лучший способ создать подзапрос в linq?

Любая помощь была бы принята с благодарностью.

Shuja

+0

Какая ошибка у вас? – SLaks

ответ

0

Вы не можете использоваться .FirstOrDefault() и .ToList() в середине запроса LINQ-SQL, который выполняется на сервере БД. Эти операции заставляют объект находиться в памяти.

Попробуйте изменить использование .FirstOrDefault() и .ToList() вместо этого используя внешнее соединение, как:

join a in db.Attributes on 
     new {AID=global_COSTCENTRE,s.Id} equals 
     new {AID=a.AttributeItemId,a.FormId} into aouter 
from x in aouter.DefaultIfEmpty().Take(1) 

Затем вы можете проверить х == нуль или нет.

Следуйте этому шаблону, и вы можете реорганизовать, даже не используя подзапросы, только внешние соединения к первой строке ни о чем.

Если все ваши объекты были в памяти, это было бы верно Linq, просто недействительным Linq-sql.

+0

Спасибо Kimbonics –