我正在尝试创建一个包含几个子查询的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中创建子查询?
非常感谢任何帮助。
舒亚
答案 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。