Как пошагово создать запрос LINQ => SQL / entity (с объединениями)? - PullRequest
2 голосов
/ 26 мая 2011

У меня есть два следующих запроса 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;
}

... но я получил "запрос"тело должно заканчиваться предложением выбора или предложением группы ".

Если я добавлю предложение выбора в конец этой функции, я не могу вызвать 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 ]

3 голосов
/ 26 мая 2011

Существует два способа написания LINQ-запросов, и хотя это не имеет большого значения, когда вы используете один, полезно знать оба из них, потому что они могут кое-что узнать о том, как работает LINQ.

Например, у вас есть набор заданий. Если бы вы выбрали все задания с идентификатором IndustryId, равным 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;
0 голосов
/ 26 мая 2011

Было бы лучше решить эту проблему путем возврата набора данных (например, общих данных) и запроса подмножества этих данных?

Например [псевдокод]

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

или аналогичных...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...