Entity framework выборка из нескольких таблиц
В предыдущей статье мы рассмотрели как создаются LINQ-запросы в Entity Framework. В этой и последующих статьях мы рассмотрим операции CRUD (create, read, update, delete) для работы с данными. Для извлечения данных из таблиц в SQL используется инструкция SELECT. Знать детали SQL-запросов вам не нужно, т.к. Entity Framework заботится о преобразовании LINQ-запросов в SQL.
Для получения всех данных из таблицы вам даже не нужно использовать LINQ-запрос, вы можете просто использовать свойство класса контекста, ссылающееся на класс модели и имеющее тип DbSet<T>. Entity Framework создаст запрос в базу данных для загрузки всех данных из таблицы, связанной с этим классом модели. Давайте добавим метод GetAllCustomers() в наш консольный проект, который мы создали ранее, чтобы извлечь все данные покупателей (т.к. мы еще не рассмотрели вставку данных с помощью Entity Framework, чтобы протестировать примеры выборки данных, вы можете заполнить таблицы Customers и Orders вручную, используя средства Visual Studio или SQL Server Management Studio):
Запрос context.Customers в этом примере извлечет все данные из таблицы Customers. Для запуска примера, вы можете вызвать метод GetAllCustomers() в методе Main() консольного приложения. Для этого примера Entity Framework сгенерирует следующий SQL-код (здесь я привожу фрагменты кода SQL для тех читателей, которые хорошо знакомы с T-SQL и хотят знать как EF транслирует запросы LINQ в SQL):
Код в этом примере возможно покажется несколько перегруженным, за счет использования псевдонима Extent1 для таблицы Customers и других псевдонимов для столбцов, а также явного указания схемы по умолчанию dbo. Это связано с тем, что Entity Framework имеет общий алгоритм построения запросов, который не только обслуживает этот очень простой запрос в примере, но также используется и для гораздо более сложных сценариев, в которых могут понадобиться эти псевдонимы.
На рисунке ниже, для наглядности, показана та область таблицы Customers, данные которой извлекаются в этом примере:
Стоит также отметить, что в этом примере мы используем отложенный LINQ-запрос. Если в вашем приложении предполагается делать несколько выборок данных в одном месте, отложенные запросы могут сильно ухудшить производительность приложения. Давайте рассмотрим пример:
Указание столбцов, условий и сортировки в запросе
В запросе данных из таблицы вы можете указать порядок сортировки, который будет использован для выборки данных. Для этого используется вспомогательный метод OrderBy(). Ниже показан пример, в котором данные заказчика сортируются по фамилии:
Приведенный выше код использует LINQ для создания запроса выборки сортированных данных из таблицы, а затем перебирает результаты запроса и отображает имя и фамилию каждого покупателя. После получения коллекции данных через свойство Customers класса контекста, вы можете использовать вспомогательные LINQ-методы OrderBy(), GroupBy() и Join() для сортировки, группировки данных на основе ключа и соединения таблиц. Эти методы будут транслированы на одноименные инструкции языка SQL.
Другой часто определяемой задачей при выборке данных, является их фильтрация на основе определенного условия. В SQL для этих целей используется оператор WHERE, LINQ содержит одноименный метод Where(), с помощью которого можно добавить дополнительное условие для загрузки данных:
В этом запросе мы выбираем всех покупателей старше 25 лет.
До сих пор мы выбирали из базы данных только коллекцию объектов модели, т.е. коллекцию IQueryable<Customer>. Зачастую извлекать все данные не нужно, а нужно извлечь данные только из определенного столбца таблицы, создавая проекцию таблицы. Такой подход позволяет улучшать производительность, когда запрашиваются данные из таблицы, содержащей много столбцов, а в приложении нужно работать только с одним или несколькими столбцами.
Например, мы могли бы захотеть выбирать только фамилии покупателей из таблицы базы данных и отбрасывать всю другую информацию. Для этих целей в LINQ используется метод Select(), которому передается делегат, в котором выбираются нужные свойства модели. Этот метод возвращает уже не коллекцию объектов Customer, а коллекцию простых типов, например, для фамилий он вернет тип IQueryable<string>. Ниже показан соответствующий пример:
Этот запрос транслируется в следующий SQL-код:
Здесь видно, что из таблицы будут выбираться данные только фамилии покупателей (столбец LastName указывается после инструкции SELECT). На рисунке ниже наглядно показано, какие данные выбирает этот запрос:
В нашем примере мы загружаем данные имен и фамилий в анонимный объект. Иногда бывает необходимо загрузить данные в объект модели, инициализировав только некоторые его свойства. В контексте нашего примера это означает, что мы могли бы создать коллекцию объектов Customers, в которую загрузили бы из базы данных всех пользователей, указав только два свойства FirstName и LastName. Для этих целей вы могли бы предположить, что нужно написать следующий пример:
Если вы запустите этот пример, то в приложении возникнет исключение NotSupportedException, в котором говорится, что Entity Framework не может использовать сложный тип Customer с запросом LINQ to Entities. Для этих целей вы должны сначала загрузить коллекцию анонимных объектов, которая инициализируется из базы данных, а затем создать коллекцию объектов Customer, которая инициализируется из коллекции анонимных объектов. Эту задачу можно выполнить в одном запросе, функционально разделив сложный запрос на две части – первая будет использоваться Entity Framework для извлечения данных из базы, вторая будет работать в памяти приложения и инициализировать коллекцию объектов Customer. В качестве разделителя нужно использовать метод AsEnumerable():
Метод AsEnumerable() в LINQ просто преобразует коллекцию IQueryable к IEnumerable. В простых приложениях, работающих с коллекциями данный метод практически не используется, т.к. в нем нет смысла – интерфейс IQueryable является производным от интерфейса IEnumerable. Но этот метод оказывает существенное влияние при использовании с Entity Framework, указывая, что цепочку методов в запросе до его вызова нужно выполнить, отправив запрос к базе данных, а последующие методы будут оперировать уже на коллекции в памяти приложения. Если вы запустите этот пример, то можете убедиться в его работоспособности.
Поиск в запросе
Пока вы видели запросы, которые возвращают коллекцию объектов из базы данных, но иногда нужно чтобы запрос возвращал один объект. Наиболее распространенным сценарием для запросов, возвращающих один объект, является поиск определенного объекта с заданным ключом. DbContext API позволяет делать это очень просто, используя метод Find() класса DbSet. Этот метод принимает значение, которое нужно найти в таблице и возвращает соответствующий объект, если он найден, или null если не найден.
Поиск в запросе в Entity Framework использует следующую последовательность:
Сначала выполняется поиск в коллекции объектов, уже загруженных из базы данных в память приложения.
Если к коллекции добавлялись новые объекты, то поиск выполняется и в них.
Выполняется поиск в базе данных в объектах, которые еще не были загружены в память приложения.
Чтобы увидеть реализацию поиска, давайте добавим новый метод FindCustomer() в котором мы будем принимать идентификатор покупателя от пользователя, путем ввода его в консоль и затем будем искать покупателя с соответствующим идентификатором в базе данных:
Метод Find() осуществляет поиск по первичному ключу таблицы. Как вы знаете, первичные ключи бывают составными, поэтому методу Find() можно передать несколько значений, для поиска в ключах, при этом эти значения должны следовать в том же порядке, в котором свойства первичных ключей определены в классе модели. Напомню, что в Code-First для этого используется атрибут аннотаций данных Column, с переданным ему параметром Order, либо метод HasColumnOrder(), если вы используете для настроек Fluent API.
Если вам нужно выполнить поиск в обычных столбцах, не являющихся ключами таблицы, то для этого можно использовать условие через метод Where(). Например, если мы хотим найти всех покупателей, чья фамилия начинается на русскую букву “В”, то можем использовать следующий запрос:
Локальные данные
Во всех предыдущих примерах мы использовали запрос к свойству класса контекста типа DbSet (context.Customers). Как говорилось ранее, использование этого свойства приводит к созданию запроса к базе для выборки всех данных из привязанной таблицы. Мы также использовали метод Find(), который ищет в памяти приложения данные до создания запроса к этой базе данных, в уже загруженных ранее данных.
Могут быть случаи, когда вы захотите использовать более сложный запрос для данных, которые уже были загружены из базы данных и находятся в памяти приложения, т.е использовать отложенный запрос, чтобы избежать повторной отправки запроса к базе данных. Например, мы могли бы загружать данные всех пользователей только при первом запуске приложения и сохранить их в каком-то локальном для приложения объекте, а затем в различных частях приложения создавать запросы к уже существующей коллекции, чтобы всякий раз не загружать ее снова.
Еще одной причиной использования такой локальной коллекции данных, является то, что в приложении в разных местах могут добавляться новые данные к этой коллекции, которые должны быть также использованы в запросах. При использовании не отложенного метода ToList(), запрос сразу же отправляется в базу данных и извлекаются данные, содержащиеся в базе данных, игнорируя новые данные в памяти приложения. Наглядно это показано на следующем примере:
Здесь, при перечислении данных покупателей, новый добавленный покупатель не будет отображаться в списке.
Entity Framework позволяет хранить локальные данные для объектов DbSet, определяя свойство Local в этом классе. Это свойство вернет все данные, которые были загружены из базы данных плюс любые добавленные новые данные в приложении. Данные, которые были помечены в приложении как удаленные, но при этом еще не удаленные из базы данных, также будут фильтроваться в запросе.
Давайте начнем с очень простой задачи и определим, сколько на текущий момент находится объектов в памяти приложения:
Этот метод позволяет проверить, сколько объектов Customer на данный момент находятся в памяти приложения. Если вы запустите приложение с вызовом этого метода, вы увидите, что количество объектов равно нулю. Мы получаем нулевой результат, потому что мы не выполняем никаких запросов, чтобы загрузить покупателей из базы данных, и мы не добавляли новые объекты Customer в коде. Давайте немного изменим этот метод, и запросим некоторые данные из базы:
У меня в базе данных находится три заказчика, поэтому данный пример вернет следующий результат:
Перебор содержимого DbSet в цикле по каждому элементу является одним из способов, чтобы получить все данные из памяти приложения, но это немного неэффективно, чтобы каждый раз выполнять цикл просто ради загрузки данных. К счастью, DbContext API включает специальный метод Load() в классе DbSet, который можно вызвать для ручного запуска процесса загрузки данных из базы. Ниже показано использование этого метода (не забудьте указать пространство имен System.Data.Entity):
Этот код гораздо лаконичнее, чем тот, что мы использовали ранее. В сборке System.Data.Entity определен также расширяющий IQueryable<T> метод Load(), поэтому мы можем использовать его не только для загрузки всех данных из таблицы, но также использовать LINQ-методы для сужения выборки. Например, следующий запрос посчитает, сколько находится в памяти объектов Customer, чей возраст превышает 25 лет:
Использование особенностей коллекции ObservableCollection
Если вы смотрели примеры использования локальных данных довольно внимательно, то должны были увидеть, что свойство Local возвращает специальный тип обобщенной коллекции ObservableCollection. Этот тип коллекции позволяет получать уведомления, когда добавляются или удаляются элементы из коллекции. Коллекция ObservableCollection полезна в ряде сценариев, работающих с привязкой данных. Например, мы ее использовали при рассмотрении WPF в статье “Привязка к коллекции объектов”, чтобы изменять графический интерфейс приложения, когда добавлялись данные.
Эта коллекция имеет событие CollectionChanged, в обработчике которого мы можем вносить полезные действия. В контексте локальных данных Entity Framework это событие возникает когда мы загружаем или удаляем данные из базы, работаем с данными в памяти приложения или добавляем новые объекты в DbContext. Ниже показан пример:
Этот код добавляет новый обработчик событий изменения коллекции локальных данных. Этот обработчик указан через лямбда-выражения, хотя можно было и добавить отдельный метод. С помощью этого обработчика мы фиксируем в консоли, когда добавляется, а когда удаляется запись из коллекции. Если вы запустите приложение с вызовом метода LocalLinqQueryies(), то вы увидите, что EF загрузит из базы данных три записи в локальную коллекцию:
Использование такого типа коллекций может упростить работу с Entity Framework в приложениях, которые работают с привязкой данных, например, в приложениях WPF.
Рассмотрим, как в EF Core выполнять фильтрацию. Для этого используем модели из прошлой темы:
Where
Если необходимо отфильтровать получаемые данные, то для этого можно использовать метод Where . Например, выберем из бд всех пользователей, которые работают в компании "Google":
Аналогичный запос с помощью операторов LINQ:
EF.Functions.Like
Начиная с версии 2.0 в Entity Framework Core можно использовать метод EF.Functions.Like() . Он позволяет транслировать условие в выражение с оператором LIKE на стороне MS SQL Server. Метод принимает два параметра - оцениваемое выражение и шаблон, с которым сравнивается его значение. Например, найдем всех пользователей, в имени которых присутствует подстрока "Tom" (это могут быть "Tom", "Tomas", "Tomek", "Smith Tom"):
На стороне БД этот запрос будет транслироваться в следующую SQL-команду:
Для определения шаблона могут применяться ряд специальных символов подстановки:
% : соответствует любой подстроке, которая может иметь любое количество символов, при этом подстрока может и не содержать ни одного символа
_ : соответствует любому одиночному символу
[ ] : соответствует одному символу, который указан в квадратных скобках
[ - ] : соответствует одному символу из определенного диапазона
[ ^ ] : соответствует одному символу, который не указан после символа ^
Стоит отметить, что в качестве первого параметра метод принимает оцениваемое выражение в виде строки. В случае со свойством Name все просто, так как оно представляет тип string. Но если нам необходимо использовать в качестве оцеениваемого выражения другие свойства, то их следует привести к строке. Например, найдем всех пользователей у которых возраст (свойство Age) в диапазоне от 22 до 29:
Например, следующее выражение:
Подобным образом метод EF.Functions.Like() можно использовать с операторами LINQ:
Для выборки одного объекта мы можем использовать метод Find() . Данный метод не является методом Linq, он определен у класса DbSet:
При выполнении запроса он будет трансформироваться в следующее выражение SQL:
First/FirstOrDefault
Но в качестве альтернативы мы можем использовать методы Linq First()/FirstOrDefault() . Они получают первый элемент выборки, который соответствует определенному условию или набору условий. Использование метода FirstOrDefault() является более гибким, так как если выборка пуста, то он вернет значение null. А метод First() в той же ситуации выбросит ошибку.
По тому же принципу работают пары методов Single/SingleOrDefault и Last/LastOrDefault , которые извлекают соответственно любой единственный элемент и последний элемент последовательности.
Добрый день! Подскажите мне пожалуйста с вопросом. Есть 2 таблицы. Users поле(Id) и вторая таблица Courses поле UserId. Во второй таблице есть поле Evaluation (Оценка (Int)). Мне нужно вытащить всех юзеров и с другой таблицы вытащить все оценки каждого юзера + суммировать их, чтобы было вида: Пользователь - Общая сумма оценок.
Юзеров (ФИО) я вытащил:
Как обьеденить мне запрос, чтобы вытащить для каждого пользователя с другой таблицы оценки и сложить их в одну?
Помогите пожалуйста друзья!
__________________Помощь в написании контрольных, курсовых и дипломных работ здесь
Выборка Entity Framework
День добрый, не могу разобраться как сделать выборку. Мне нужно получить ID продукта (int), если.
Выборка в диапазоне. Entity framework
Если использовать такую конструкцию var query = db.Items.Where(/*тут длинное условие выборки*/);.
Entity Framework. Выборка из модели
У меня есть БД с одной таблицей. Таблица Customers. ID_cust Date Surname Name Patr Address.
Как реализовать маппинг нескольких таблиц БД на один класс (Entity Framework)
как реализовать маппинг нескольких таблиц БД на один класс? Или наоборот - одну таблицу на.
Решение
master_fatum,
Подразумевается, что в сущности User есть навигационное свойство Courses.
На будущее: выкладывайте описание сущностей, не застваляйте за вас придумывать как они должны выглядеть.
Одно не понятно, как ты вызвал на таблице Courses метод расширения Sum.master_fatum, это метод-расширения LINQ, которые доступен для всех коллекций (реализующих IEnumerable).
Подразумевается, что класс User выглядит примерно так:
Это скажет EF'у, что между User и Course есть связь и какого она типа. А так же позволит строить запросы с выгребанием связанных данных по типу того, что я выше показал.А возможно ли без этого автоматического свойства? Возможно как-то собрать запрос с Union? Как оказалось, его нет ни в базе ни в объекте. Миграцию делать не вариант.
Добавлено через 2 часа 28 минут
public ICollection<Course> Courses < get; set; >добавил в объект Users. Какого типа должно быть данное поле в БД? И вобоще, должно оно быть? Должен ли он быть FK? Запутался я совсем.
Возможно, но запрос будет более многословный.
Как оказалось, его нет ни в базе ни в объекте. Миграцию делать не вариант.Какая ещё миграция? Это вопрос модели данных, схема базы-то у вас уже соответствующая. Осталось только одно единственное свойство добавить в класс. Это не сложно. Почитайте мануал по EF, а то как-то.
Какого типа должно быть данное поле в БД? И вобоще, должно оно быть? Должен ли он быть FK? Запутался я совсем. Внешний ключ должен быть в таблице Course и должен указывать на таблицу User . Судя по первому вашему посту, это уже есть. Иначе вы никак запрос бы не могли составить.Помогите пожалуйста разобраться! Пол года не садился за код и забыл уже и EF и всё остальное.
Вот структура БД:
Добавил в класс соответствующее свойство ICollection<Course>
Я понимаю, что трабла именно с этим свойством. Что я не так делаю?
Вот сам метод, где я пытаюсь прибилдиться к DGV:
Ну так вы в тексте исключения сами почитайте. Я не экстрасенс по скриншоту MessageBox'а проблемы определять.
А вот это уже дерёвня. "Курсы" - Courses. То, что ваши таблицы во множественном - есть нормально. Это же хранилище множества записей. Но сущности в коде должны быть в единственном числе, ибо представляют из себя отдельные записи, а не таблицу в целом. Соответственно, User и Course. Но их коллекции (в коде) - Users и Courses. А вот это уже дерёвня. "Курсы" - Courses. То, что ваши таблицы во множественном - есть нормально. Это же хранилище множества записей. Но сущности в коде должны быть в единственном числе, ибо представляют из себя отдельные записи, а не таблицу в целом. Соответственно, User и Course. Но их коллекции (в коде) - Users и Courses. Изначально код писал не я. Но мне сейчас приходится его читать и переписывать. master_fatum, так проведите рефакторинг. Это минута работы. Переименовать классы и некоторые свойства и добавить маппинг, чтобы EF знал, что сущности User и Course мапятся на таблицу с множественным названием. И всё. так проведите рефакторинг. Это минута работы. Переименовать классы и некоторые свойства и добавить маппинг, чтобы EF знал, что сущности User и Course мапятся на таблицу с множественным названием. И всё.Рефакторингом я хотел заняться в последнюю очередь. Это не основная сейчас проблема. Мне нужно решить проблему, по которой попросил помощи.
Добавлено через 3 минуты
А вообще отношение сущностей и таблиц в БД верное? В таблице Курсы есть столбец UserId, он FK на таблицу Юзерс. Не могу понять, почему при добавлении свойства ICollection<Course> начинает вылетать эксепшн. Трассировка особо ничего не показывает либо я во что-то не въезжаю.
Дак вы даже эксепшен не процитировали. Вам уже намекнули про неинформативность messagebox.
Если ругается про null на коллекции, то наверное не хватает .Include() для этой связанной таблицы.
Нет. У вас сейчас курс уникальный и персональный для каждого пользователя. Ерунда какая-то. В реальной жизни Курс не привязан к пользователю. Один и тот же курс может одновременно проходить куча народа. Точно так же, как один человек может быть записан на несколько разных курсов.
Тут, видимо, просится отношение многие ко многим. Значит нужна промежуточная таблица UserToCourse. Там будут внешние ключи на пользователя и курс. И всякие оценки пользователя по этому курсу или что вам там надо.
Не могу понять, почему при добавлении свойства ICollection<Course> начинает вылетать эксепшн. И не поймёте никогда, пока под отладкой не запустите своё приложение. По-вашему, разработчики как свой код отлаживают? На форму бегают с кусками своего кода? Нет. У вас сейчас курс уникальный и персональный для каждого пользователя. Ерунда какая-то. В реальной жизни Курс не привязан к пользователю. Один и тот же курс может одновременно проходить куча народа. Точно так же, как один человек может быть записан на несколько разных курсов.Каждый пользователь пишет, какие он прошёл курсы. Связь один ко многим. Вы сам контекст не правильно поняли. Тут всё верно.
Вот что говорит отладчик:
Свойства и члены все пустые. После выполнения шага с обходом (F10), вылетает пустое WPF окно без таблицы. Когда я обращаюсь вообще к другой таблице (Читай функции), вылетает эксепшн (Выше скрин.). Удаляю (Или коммент) из объекта Users свойство public ICollection<Course> Courses < get; set; >, всё нормально начитает работать. И в том числе метод:
Отрабатывает нормально, вытаскивает ФИО.
Просто сложно объяснить непонятную траблу.
Если у вас есть возможность, помогите мне с запросом. Я потом сам допедрю со свойствами. Сейчас просто уже времени не остаётся. Когда я обращаюсь вообще к другой таблице (Читай функции), вылетает эксепшн (Выше скрин.).А эксепшен-то где?
Добавлено через 1 минуту
Решение
Выборка только одной строки. Entity Framework
Как извлечь данные из client, если я знаю, что там будет только одна запись? Такой код работает.
Entity Framework 6 использование нескольких БД
Всем привет! Столкнулся с проблемой и ни как не могу найти решения. Есть 3 сервера на них в.
Связь таблиц 1 к многим (Entity framework Code First)
Доброго времени суток! Пожалуйста помогите связать 2 поля: //Класс объявлений public.
Операции Update и Delete в entity framework в отношении таблиц many-to-many. DB first
Всем салют! Собственно главная идея вопроса изложена в заголовке. Использую Entity Framework. К.
Они имеют отношение один ко многим в моем решении. Один клиент имеет много транзакций, а одна транзакция имеет одного клиента. Если бы я хотел собрать 10 последних транзакций и 10 последних клиентов в одном запросе LINQ, как бы я это сделал? Я читал, что .Union() должен быть в состоянии сделать это, но он не будет работать для меня. Пример:
Это дает мне два списка типа Guid , но они содержат одинаковые элементы. Не уверен, что это только я, кто понимает это неправильно, но это кажется немного странным. Я счастлив, пока он запрашивает базу данных один раз.
Я хотел получить 10 последних транзакций и 10 последних клиентов в одном запросе LINQ.
Немного неясно, что вы хотите. Я сомневаюсь, что вы хотите одну последовательность с сочетанием клиентов и транзакций. Я предполагаю, что вы хотите 10 новых клиентов, каждый из которых имеет свои последние 10 транзакций?
Интересно, почему вы отклоняетесь от первых соглашений, касающихся кода структуры сущностей? Если ваш класс Customer представляет строку в вашей базе данных, то наверняка у него нет HashSet<Transaction> ?
Customer один ко многим" с его Transactions должен быть смоделирован следующим образом:
Это все, что должна знать инфраструктура сущностей для определения таблиц, которые вы хотите создать, для определения ваших отношений "один ко многим" и для обнаружения первичных ключей и внешних ключей. Только если вам нужны разные имена таблиц или столбцов, вам понадобятся атрибуты и/или свободный API
Основное различие между моими и вашими классами состоит в том, что отношение "один ко многим" представлено виртуальными свойствами. HashSet - это ICollection. В конце концов, ваша таблица Transactions представляет собой набор строк, а не HashSet
В каркасе сущностей столбцы ваших таблиц представлены не виртуальными свойствами; виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим. )
Довольно много людей склонны (group-) присоединяться к таблицам, когда они используют каркас сущностей. Тем не менее, жизнь намного проще, если вы используете виртуальные свойства
Вернуться к вашему вопросу
Я хочу (некоторые свойства) 10 новых клиентов, каждый из которых (несколько свойств) их 10 последних сделок
Структура сущности знает отношение один-ко-многим и признает, что для этого необходимо соединение group-.
Одна из более медленных частей вашего запроса - передача выбранных данных из СУБД в локальный процесс. Следовательно, разумно ограничить выбранные данные теми данными, которые вы фактически планируете использовать. Если у Клиента с Id 4 есть 1000 Транзакций, было бы бесполезно передавать внешний ключ для каждой Транзакции, потому что вы знаете, что он имеет значение 4.
Всем доброго времени суток, просьба помочь в деле, сижу уже третий день и не могу понять по какой причине в SQL Management Studio данные запросом выбираются корректно а при использовании EF иначе.
Необходимо сделать отображение объявления как на авто или авито не важно, с использованием изображений.
В общем имеется куча связанных таблиц более чем две ,это пользователи, комментарии к объявлению, марка авто, модель, характеристики, и изображения. Чтобы не гонять туда суда огромный запрос, либо на Linq либо на прямом SQL через SQlQuery я создал представление в БД, с использованием всех этих таблиц:
Сам запрос к этому представлению с выборкой по Id-у объявления в SQLManagement:
Суть в том что возвращаются разные данные в столбце PathPhoto я это сделал для того чтобы потом уже при возврате данных непосредственно на сервере в коде выбрать из этого столбца нужные мне значения для отображения на странице.
Но вот парадокс или мой косяк, где, уже все перепробовал, от работы с обычными типами и Linq до прямых запросов, данные возвращаются одни и те же это заметно по возвращаемым значениям столбца или уже свойства PаthPhoto в перечислении:
Использовать представления решил по той причине, что размер запроса реально велик, там учитываются более 10 столбцов, и несколько таблиц, думаю разумнее сделать его на сервере, выбор пал на представления. хотя как читал можно и функцию использовать которая возвращает мне нужные данные, правда опыта нет с этим пока, а уже сроки сдачи курсовой жмут. Вот и решил попробовать так. Еще фишка с изошками, ранее я делал отдельный запрос к таблице Images где выбирал нужные мне изо по Id-у, но подумал, что как то не совсем хорош получается сразу к одной странице два запроса делать. А если в бой вступает EF как я уже сам убедился. запрос просто раздувается как незнамо кто и что, и что еще страшнее становится вложенным.. когда, допустим делаю так :
Просьба описать, что можно решить, я уже просто опустил руки с этой возней:) Хотя бы на словах, в какую рыть сторону. И правильно ли я поступил в данной ситуации?
Я думаю, что на этапе создания прототипа, не надо заморачиваться с представлениями, лучше делайте чтобы быстрее получить работающий вариант. На самом деле время на обмен sql запросом гораздо меньше других факторов влияющих на производительность при использовании EF (change tracking, оптимальность запроса и т.д.) Все равно, если вы захотите чтобы очень быстро все работало - EF может и не подойти (dapper в помощь). По поводу вашей проблемы, без разбора запросов неясно что там происходит.
Благодарен за ответ, разобрался, данные подгружать стал простым запросом на выборку значений из БД, ведь не двоичный формат таскаю, а всего лишь три строковых значения. Немного повозился с кэшированием, через [OutputCache]
Читайте также: