C#LInq子查询问题

时间:2014-12-31 16:28:47

标签: linq linq-to-sql subquery

我正在尝试创建一个包含几个子查询的linq查询。我创建的查询似乎是正确的(至少在语法中)但我没有发回任何数据,Fiddler在此查询中显示错误:

        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中创建子查询?

非常感谢任何帮助。

舒亚

1 个答案:

答案 0 :(得分:0)

您不能在db服务器上执行的LINQ-SQL查询中使用.FirstOrDefault()和.ToList()。这些操作会强制对象进入内存。

尝试将.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)

然后你可以测试x == null。

遵循这种模式,您可以重构甚至不使用子查询,只需外部联接到第一行就没有了。

如果所有对象都在内存中,这将是有效的Linq,只是无效的Linq-sql。