Entity Framework и большие запросы.Что практично? - PullRequest
2 голосов
/ 23 декабря 2011

Я из старой школы, где в БД был весь доступ к данным, инкапсулированный в представления, процедуры и т. Д. Теперь я вынужден использовать LINQ для большинства очевидных запросов.

Что мне интересно, так это когда останавливаться и что практично? Сегодня мне нужно было выполнить запрос так:

SELECT D.DeviceKey, D.DeviceId, DR.DriverId, TR.TruckId, LP.Description
FROM dbo.MBLDevice D
LEFT OUTER JOIN dbo.DSPDriver DR ON D.DeviceKey = DR.DeviceKey
LEFT OUTER JOIN dbo.DSPTruck TR ON D.DeviceKey = TR.DeviceKey
LEFT OUTER JOIN 
    (
    SELECT LastPositions.DeviceKey, P.Description, P.Latitude, P.Longitude, P.Speed, P.DeviceTime 
    FROM dbo.MBLPosition P
    INNER JOIN 
    (
        SELECT D.DeviceKey, MAX(P.PositionKey) LastPositionKey 
        FROM dbo.MBLPosition P
        INNER JOIN dbo.MBLDevice D ON P.DeviceKey = D.DeviceKey
        GROUP BY D.DeviceKey
    ) LastPositions ON P.PositionKey = LastPositions.LastPositionKey 
    ) LP ON D.DeviceKey = LP.DeviceKey
WHERE D.IsActive = 1

Лично я не могу написать соответствующий LINQ. Итак, я нашел инструмент онлайн и вернулся на 2 страницы LINQ. Это работает должным образом - я вижу это в профилировщике, но это не поддерживаемый IMO. Другая проблема заключается в том, что я делаю проекцию и возвращаю анонимный объект. Или я могу вручную создать класс и спроецировать в этот пользовательский класс.

На данный момент мне интересно, лучше ли создать View на SQL Server и добавить его в мою модель? Это сломает мою мантру «все SQL на стороне клиента», но будет легче читать и поддерживать. Нет

Интересно, где вы остановились на T-SQL против LINQ?

EDIT

  • Описание модели.
  • У меня есть DSPTrucks, DSPDrivers и MBLDevices.
  • Устройство может быть подключено к грузовику, водителю или к обоим.
  • У меня также есть MBLPositions, который в основном пингует от устройства (отметка времени и положение GPS)

Что делает этот запрос - за один раз он возвращает всю информацию о драйвере устройства, так что я знаю, к чему подключено это устройство, и он также получает последнюю позицию GPS для этих устройств. Ответ может выглядеть так:

enter image description here

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

Ответы [ 3 ]

2 голосов
/ 23 декабря 2011

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

Однако, когда вы попадаете в точку, когда соответствующий запрос LINQ становится труднее писать и поддерживать, тогда какой смысл в действительности? Поэтому я бы просто оставил этот запрос на месте. Это работает, в конце концов. Чтобы упростить использование, достаточно просто отобразить представление или кашель хранимую процедуру в вашей модели EF. Ничего плохого, правда (ИМО).

0 голосов
/ 23 декабря 2011

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

С точки зрения sql, который он генерирует как поддерживаемый, вам не следует беспокоиться о том, что SQL можно обслуживать, а о запросе LINQ, который генерирует SQL.

В конце концов, если sql не совсем прав, я полагаю, что вы можете сделать несколько вещей, чтобы заставить LINQ генерировать SQL в нужном направлении ... в некоторой степени.

AFAIK Нет никаких проблем с возвращением анонимных объектов, однако, если вы делаете это в нескольких местах, вы можете создать класс, чтобы держать вещи в порядке.

0 голосов
/ 23 декабря 2011

Сначала вы можете хранить запросы Linq в переменных, что может сделать их не только более читабельными, но и многократно используемыми.

Примером может быть следующий:

        var redCars = from c in cars
                      where c.Colour == "red"
                      select c;

        var redSportsCars = from c in redCars
                            where c.Type == "Sports"
                            select c;

Запросы выполняются лениво и не составляются, пока вы не скомпилируете их или не выполните итерацию по ним, поэтому в профилировщике вы заметите, что это действительно эффективный запрос

Вы также выиграете от определения отношений в модели и использования свойств навигации вместо использования синтаксиса соединения linq. Это (опять же) сделает эти отношения повторно используемыми между запросами и сделает их более читаемыми (поскольку вы не указываете отношения в запросе, как в приведенном выше SQL)

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

За исключением CTE (что я вполне уверен, что вы не можете сделать в LINQ), я бы написал все запросы в LINQ в эти дни

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