如何逐步构建 LINQ => SQL/实体查询(带联接)?



我有以下两个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);

或类似的。。。

相关内容

  • 没有找到相关文章

最新更新