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

时间:2011-05-26 06:43:34

标签: c# linq linq-to-sql linq-to-entities

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

有没有办法逐步构建此查询以避免重复大量代码?

2 个答案:

答案 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);

或类似......