chinnuTest Ответов: 2

Преобразование SQL - запроса в C# LINQ qu


Всем Привет,

Я новичок в написании запросов linq. Я действительно написал SQL-запрос , который дает результаты,как и ожидалось , мне нужно преобразовать его в LINQ c# query, у нас нет разрешений на установку Linqer, не могли бы вы, пожалуйста, кто-нибудь помочь мне в этом. Спасибо. Вот мой SQL запрос

select * from PatVisit p
inner join Device d on d.PattId = p.PatId and d.SyncDate is not null
where p.VisitDate in
( select max(VisitDate) from PatVisit pv where VisitId in (4,7,2,8,9) group by PatId )
and DATEDIFF(d,p.visitDate,GETDATE()) <10


Что я уже пробовал:

Попробовал LinqPad, но я не могу конвертировать там.

0x01AA

"Попробовал LinqPad, но я не могу конвертировать там."
*зевать*
а.) в чем была _exactly_ проблема, где вы потерпели неудачу?
Б) есть ли желание попробовать что-то другое?

Maciej Los

Вы используете in предложение дважды, так что ваш запрос неэффективен. Вы должны переосмыслить это!

2 Ответов

Рейтинг:
13

Maciej Los

Пожалуйста, сначала прочтите мой комментарий к этому вопросу.

Как я уже упоминал ваш запрос не является эффективным из-за использования [in] пункт второй раз.

Давайте попробуем улучшить ваш sql-запрос. Итак, это:

select * from PatVisit p
inner join Device d on d.PattId = p.PatId and d.SyncDate is not null
where p.VisitDate in
( select max(VisitDate) from PatVisit pv where VisitId in (4,7,2,8,9) group by PatId )
and DATEDIFF(d,p.visitDate,GETDATE()) <10

можно заменить на это:
DECLARE @finaldate DATETIME
SELECT @finaldate = DATEADD('d', -10, GETDATE())

SELECT p.*
FROM
(
    SELECT p1.*, ROW_NUMBER() OVER(PARTITION BY p1.PatId ORDER BY p1.VisitDate DESC) RowNo
    FROM PatVisit p1
    WHERE p1.VisitDate >= @finaldate AND p1.VisitId IN(4,7,2,8,9) 
) p INNER JOIN Device d on d.PattId = p.PatId and d.SyncDate is not null
WHERE p.RowNo=1;

Как вы можете видеть, я использовал Функция ROW_NUMBER() [^], что очень полезно для получения только первой строки из вложенного запроса.
Заметить что WHERE условие не содержит функция DateDiff[^] функция, потому что вы можете ограничить свои данные путем сравнения VisitDate до окончательной даты (хранится в @finaldate переменная).

Вышеприведенный запрос можно было бы - вероятно - улучшить еще больше, но у меня нет доступа к вашим данным и я не вижу вашей структуры данных...

Что касается запроса linq...
Нет никакого соответствия [IN] пункт в Linq, но... мы можем использовать Где[^] вместе с Какой-нибудь[^] метод. Видеть:
int[] vid2get = new int[]{4,7,2,8,9};
var qry1 = PatVisit_context
	.Where(x=> vid2get.Any(y=>y==x.VisitId));


Таким образом, окончательная версия запроса linq может выглядеть следующим образом:

int[] vid2get = new int[]{4,7,2,8,9};
DateTime finaldate = DateTime.Now.AddDays(-10);
var qry1 = (from pv in PatVisit_context
	.Where(x=> vid2get.Any(y=>y==x.VisitId) && x.VisitDate >= finaldate)
	.GroupBy(x=> x.PatId)
	.Select(grp=> grp.OrderByDescending(y=>y.VisitDate).First())
	join d in Device_context on pv.PatId equals d.PatId && d.SyncDate != null
	select pv)
	.ToList();


Удачи вам!


phil.o

5 б

Maciej Los

Спасибо, Оливье.

chinnuTest

Большое вам спасибо за подробный запрос,я очень признателен. вы сделали мой день... запрос, который вы дали, работает идеально. Но вы не присоединились к таблице устройств, если это возможно, не могли бы вы присоединиться к этой таблице устройств и условию ниже запроса linq ?

int[] vid2get = new int[]{4,7,2,8,9};
Finaldate датавремя = Датавремя.Сейчас.AddDays(-10);
ВАР qry1 = PatVisit_context
.Где(x=> vid2get.Любой(г=&ГТ;у==Х.Усилитель VisitId) &;&амп; х.VisitDate &ГТ;= finaldate)
.GroupBy(x=> x.PatId)
.Выберите(ГРП=&ГТ; стеклопластик.OrderByDescending(г=&ГТ;г.VisitDate).Первый())
.Список();

Maciej Los

Проверьте обновленный ответ.

chinnuTest

Огромное спасибо.. Спасибо за вашу помощь...

Maciej Los

Всегда пожалуйста.

Рейтинг:
0

MarcusCole6833

Первый порт захода

Основные операции запросов LINQ (C#) | Microsoft Docs[^]


во вторых посмотрите примеры здесь

Использование запросов LINQ[^]