我有以下两个LINQ查询:
public int getJobsCount()
{
var numJobs =
(from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
select j).Count();
return numJobs;
}
public List<Job> getJobs()
{
var jobs =
(
from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
orderby j.issueDatetime descending
select new Job { x = j.field, y = c.field, etc }
).Skip(startJob - 1).Take(numJobs);
return jobs;
}
那里有很多重复的代码 - “from”和“join”行是相同的,我将添加一些“where”行也是相同的。
我尝试添加一个为第一部分返回IQueryable的方法:
public IQueryable getJobsQuery()
{
var q =
from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id;
return q;
}
...但我得到“查询正文必须以select子句或group子句结束”。
如果我在该函数的末尾添加一个select子句,我就不能在结果上调用count():
// getJobsQuery:
var q = from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
select new { a = j.y, b = c.z }
// another method:
var q = getJobsQuery();
var numJobs = q.Count(); // "IQueryable doesn't contain a definition for count"
有没有办法逐步构建此查询以避免重复大量代码?
答案 0 :(得分:3)
有两种编写LINQ查询的方法,虽然使用它并不重要,但是如果知道它们两者,那么它们可能会让你了解LINQ的工作原理。
例如,您有一组工作。如果您要选择行业ID为5的所有作业(通常猜测数据类型),您可能会写这样的内容:
from j in dbConnection.jobs
where j.inustryId == 5
select j;
同样的查询也可以像这样编写
dbConnections.jobs.Where(j => j.industryId == 5);
现在,我不是在这里宣扬说一种方式比另一种更好,但是在这里你可以清楚地看到LINQ如何使用扩展方法语法自动选择迭代对象(除非你选择),而在查询语法中,您必须明确地执行此操作。此外,如果你在这里添加另一个where子句,它将看起来像这样:
from j in dbConnection.jobs
where j.inustryId == 5 // not using && here just to prove a point
where j.cityId == 3 // I THINK this is valid syntax, I don't really use the query-syntax in linq
select j;
在扩展方法中,您可以添加更多方法调用,如下所示:
dbConnections.jobs.Where(j => j.industryId == 5)
.Where(j => j.cityId == 3);
现在很高兴知道原因这意味着你可以将你的linq查询放在一个函数中继续查询它。而你需要做的只是明确选择起始变量j,或者你需要的所有变量:
var q =
from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id;
select new {j = j, i = i, c = c, s = s, pt = pt };
return q;
然后你应该能够做到这一点:
getJobsQuery().Where(a => a.i.id == 5); // I used a as a name for "all", like the collection of variables
或使用查询语法
from a in getJobsQuery()
where a.i.id == 5
select a;
答案 1 :(得分:0)
通过返回一组数据(例如公共数据)并查询该数据的子集,可以更好地解决这个问题吗?
E.g。 [伪]
var allJobs =
(from j in dbConnection.jobs
join i in dbConnection.industries on j.industryId equals i.id
join c in dbConnection.cities on j.cityId equals c.id
join s in dbConnection.states on j.stateId equals s.id
join pt in dbConnection.positionTypes on j.positionTypeId equals pt.id
select j);
var myJobs = allJobs.OrderBy(j => j.issuedate).skip(expr).Take(allJobs.Count);
或类似......