我有以下两个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"one_answers"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"
有没有一种方法可以逐步构建这个查询,以避免重复大量代码?
有两种编写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;
返回一组数据(例如公共数据)并查询该数据的子集会更好地解决这个问题吗?
例如[伪代码]
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);
或类似的。。。