Linq-запрос с объединениями таблиц, инструкциями case, count, group by - PullRequest
0 голосов
/ 19 февраля 2012

Я хочу выполнить запрос linq, который вернет значения в мой пользовательский DTO.Этот конкретный запрос linq должен будет учитывать объединения из нескольких таблиц с использованием операторов регистра переключателя, count (*) и группировки по

. Это пример SQL-версии запроса, для которого мне потребуется эквивалент LinQ...

select 
slm.SLType, 
count(c.EStatID) as EStat, 
COUNT(cpd.TrId) as Training,
COUNT(
CASE WHEN cpd.TrStat=  44 THEN  1 
     WHEN cpd.TrStat!=  44 THEN NULL 
     WHEN cpd.TrStat IS NULL  THEN  NULL 
END) as TrainingComplete,
COUNT(
CASE WHEN cpd.CndAssess =  44 THEN  1 
     WHEN cpd.CndAssess !=  44 THEN NULL 
     WHEN cpd.CndAssess IS NULL  THEN  NULL 
END) as AssessmentComplete
from TabC c , TabCPD cpd, TabSLM slm 
where cpd.SLid = slm.SLid
and c.Id= cpd.CID
and c.O_Id = 1
group by slm.SLType 

Возвращает записи в следующем формате.Я поместил каждую запись как новую строку с полями, разделенными запятыми.Указанные ниже цифры приведены в качестве примера.

TypeA, 0 , 1 , 1, 0 
TypeB, 1 , 0 , 1, 0

Я пытаюсь создать запрос linq в формате, аналогичном приведенному ниже, без особой удачи

var query = 
    from c in TabC, ...... 
    select new MyCustomTableC_DTO
    {
      DTOproperty = c.MatchingTable property,....
    }

MyCustomTableC_DTO будет иметь свойствокаждое поле в запросе.Есть идеи, как этого добиться?Запрос, который я буду использовать для создания списка типа MyCustomTableC_DTO

Спасибо за ваше время ...

1 Ответ

7 голосов
/ 20 февраля 2012

Когда вы пытаетесь преобразовать этот оператор SQL в LINQ построчно, вы получите что-то вроде этого:

from row in (
    from c in db.TabC
    from cpd in db.TabPD
    from slm in db.TabSLM
    where cpd.SLid == slm.SLid
    where c.Id == cpd.CID
    where c.O_Id == 1
    select new { c, cpd, slm })
group row in row.slm.SLType into g
select new
{
    SLType = g.Key,
    EStat = g.Count(r => r.c.EstatID != null),
    Training = g.Count(r => r.cpd.TrId != null),
    TrainingComplete =
        g.Count(r => r.cpd.TrStat == 44),
    AssessmentComplete =
        g.Count(r => r.cpd.CndAssess == 44)
};

Однако этот запрос усложняет ситуацию и полностью игнорирует тот факт, что Entity Framework знает гораздо больше о модели и генерирует все внешние ключи как свойства для сущностей. Кроме того, с LINQ вам часто приходится подходить к чему-то другому. Например, в вашем случае не начинайте с сущности TabC или TabSLM, а TabPD, поскольку эта таблица является кросс-таблицей. Обладая этими знаниями, мы можем написать запрос LINQ следующим образом:

from cpd in db.TabCPDs
where cpd.TabC.O_Id == 1
group cpd by cpd.TabSLM.SLType into g
select new
{
    SLType = g.Key,
    EStat = g.Count(r => r.TabC.EstatID != null),
    Training = g.Count(r => r.TrId != null),
    TrainingComplete =
        g.Count(r => r.TrStat == 44),
    AssessmentComplete =
        g.Count(r => r.CndAssess == 44)        
};

Это намного проще и (если я не ошибаюсь) имеет тот же результат.

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