LINQ - НЕ выбираете определенные поля? - PullRequest
9 голосов
/ 30 мая 2009

У меня есть запрос LINQ, сопоставленный с Entity Framework, который выглядит примерно так:

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Single();

Возвращает один объект изображения и работает так, как задумано.

Однако этот запрос возвращает все свойства моей таблицы изображений в БД. При нормальных обстоятельствах это было бы хорошо, но эти изображения содержат много двоичных данных, которые возвращаются очень долго.

По сути, в текущем состоянии мой запрос linq делает:

Select ImageId, Name, Data
From Images
...

Но мне нужен запрос, который выполняет эту задачу:

Select ImageId, Name
From Images
...

Обратите внимание, я хочу загрузить все, кроме данных. (Я могу получить эти данные на втором асинхронном проходе)

Ответы [ 5 ]

8 голосов
/ 02 июня 2009

К сожалению, если использовать LINQ to SQL, оптимального решения не существует.

У вас есть 3 варианта:

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

Мне нравится LINQ to SQL, но так оно и есть.

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

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

ура

1 голос
/ 30 января 2014

Вы не можете сделать это с LINQ , по крайней мере, на данный момент ...

Лучший из известных мне подходов - создать View для нужной таблицы без больших полей и использовать LINQ с этим View.

1 голос
/ 01 июня 2009

[При использовании Linq 2 SQL] В конструкторе DBML есть возможность загружать отдельные столбцы таблицы с задержкой. Установите это значение true для вашего большого двоичного поля. Затем эти данные не загружаются до тех пор, пока они фактически не будут использованы.

[Вопрос для всех вас: кто-нибудь знает, поддерживают ли платформы сущностей отложенную загрузку varbinary / varchar в MSVS 2010? ]

Решение № 2 (для сущности или linq 2 sql):

Создание представления таблицы, включающей только первичный ключ и varchar (max) / varbinary (max). Отобразите это в EF.

В своем конструкторе Entity Framework удалите свойство varbinary (max) / varchar (max) из определения таблицы (оставив его только в представлении). Это должно исключить поле из операций чтения / записи в эту таблицу, хотя вы можете проверить это с помощью регистратора.

Как правило, вы будете получать доступ к данным через таблицу, которая исключает большой двоичный объект. Когда вам нужен BLOB-объект, вы загружаете строку из представления. Я не уверен, что вы сможете писать в представление, я не уверен, как вы будете писать. Возможно, вы сможете записать в представление, или вам может понадобиться написать хранимую процедуру, или вы можете создать файл DBML для одной таблицы.

1 голос
/ 30 мая 2009

Это создаст новое изображение только с установленными полями. Когда вы вернетесь, чтобы получить данные для выбранных изображений, я бы предложил продолжить и получить полный набор данных, а не пытаться объединить его с существующими данными идентификатора / имени. Поля id / name предположительно малы по отношению к данным, и код будет намного проще, чем попытка выполнить слияние. Кроме того, может и не потребоваться создание объекта Image, поскольку анонимный тип также вполне может соответствовать вашим целям.

image = this.Context.ImageSet
                    .Where(n => n.ImageId == imageId)
                    .Where(n => n.Albums.IsPublic == true)
                    .Select( n => new Image { ImageId = n.ImageId, Name = n.Name }
                    .Single();
0 голосов
/ 01 июня 2009

В качестве альтернативы вы можете использовать select new в выражении запроса ...

var image =
(
    from i in db.ImageSet
    where i.ImageId == imageId && i.Albums.IsPublic
    select new
    {
        ImageId = i.ImageId,
        Name = i.Name
    }
).Single()

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

Спасибо :)

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