Ответ 1
Да вы можете возвращать только подмножество столбцов с помощью проецирования:
var result = from x in context.LargeTable
select new { x.Id, x.Name };
Проблема: проекция и интенсивная загрузка не работают вместе. После того, как вы начнете использовать прогнозы или пользовательские соединения, вы меняете форму запроса, и вы не можете использовать Include
(EF проигнорирует его). Единственный способ в таком сценарии - вручную включить отношения в проецируемый набор результатов:
var result = from x in context.LargeTable
select new {
Id = x.Id,
Name = x.Name,
// You can filter or project relations as well
RelatedEnitites = x.SomeRelation.Where(...)
};
Вы также можете проецировать определенный тип BUT, но не должен отображаться конкретный тип (поэтому вы не можете, например, проектировать объект LargeTable
из моего примера). Проецирование отображаемого объекта может выполняться только по материализованным данным в Linq-to-objects.
Edit:
Возможно, есть некоторые недоразумения в отношении того, как работает EF. EF работает поверх объектов - объект - это то, что вы сопоставили. Если вы сопоставляете 500 столбцам с сущностью, EF просто использует этот объект, как вы его определили. Это означает, что запрос на загрузку объекта и сохранение сохраняет объект.
Почему он работает таким образом? Объект рассматривается как структура атомных данных, и его данные могут быть загружены и отслеживаться только один раз - это ключевая функция для способности правильно сохранять изменения в базе данных. Это не означает, что вам не нужно загружать только подмножество столбцов, если вам это нужно, но вы должны понимать, что загрузка подмножества столбцов не определяет ваш исходный объект - это считается произвольным представлением данных в вашей организации. Это представление не отслеживается и не может сохраняться в базе данных без дополнительных усилий (просто потому, что EF не содержит никакой информации о происхождении проекции).
EF также помещают некоторые дополнительные ограничения на способность сопоставлять сущность
- Каждая таблица обычно может отображаться только один раз. Зачем? Опять же, поскольку таблица сопоставления несколько раз для разных объектов может нарушить способность правильно сохранять эти объекты - например, если какой-либо неклассический столбец отображается дважды, и вы загружаете экземпляр обоих объектов, сопоставленных с одной и той же записью, которые из отображаемых значений будут использоваться во время сохранение изменений?
- Есть два исключения, которые позволяют вам сопоставлять таблицу несколько раз
- Таблица на наследование иерархии - это сопоставление, в котором таблица может содержать записи из нескольких типов сущностей, определенных в иерархии наследования. Столбцы, сопоставленные базовому объекту в иерархии, должны совместно использоваться всеми объектами. Каждый тип производного объекта может иметь свои собственные столбцы, сопоставленные с его конкретными свойствами (другие типы сущностей имеют эти столбцы всегда пусты). Нельзя разделить столбец для производных свойств среди нескольких объектов. Также должен быть один дополнительный столбец, называемый дискриминатором, указывающий EF, какой тип сущности хранится в записи, - эти столбцы не могут быть отображены как свойство, поскольку он уже отображается как дискриминатор типа.
- Разделение таблиц - это прямое решение для ограничения отображения одиночной таблицы. Это позволяет вам разбивать таблицу на несколько объектов с некоторыми ограничениями:
- Между объектами должно быть взаимно однозначное отношение. У вас есть один центральный объект, используемый для загрузки основных данных, и все остальные объекты доступны через свойства навигации из этого объекта. Желательная загрузка, ленивая загрузка и явная загрузка обычно работают.
- Отношение вещественно 1-1, так что обе части или отношение всегда должны существовать.
- Сущности не должны делиться каким-либо свойством, кроме ключа - это ограничение разрешит начальную проблему, потому что каждое изменяемое свойство отображается только один раз
- Каждый объект из таблицы split должен иметь свойство отображаемого ключа
- Вставка требует, чтобы весь граф объекта был заполнен, поскольку другие объекты могут содержать сопоставленные требуемые столбцы.
Linq-to-Sql также содержит возможность отмечать столбец как ленивый, но эта функция в настоящее время недоступна в EF - вы можете голосовать за эту функцию.
Это приводит к вашим вариантам оптимизации
- Использовать прогнозы для получения "представления" только для чтения для объекта
- Вы можете сделать это в запросе Linq, как я показал в предыдущей части этого ответа.
- Вы можете создать представление базы данных и отобразить его как новый "объект"
- В EDMX вы также можете использовать Defining query или Query view для инкапсуляции проекции SQL или ESQL в ваше сопоставление.
- Использование разделения таблиц
- EDMX позволяет без проблем разбивать таблицу на многие объекты.
- Код сначала позволяет вам разбивать таблицуно есть некоторые проблемы, когда вы разделяете таблицу на более чем два объекта (я думаю, для каждого типа сущности требуется, чтобы свойство навигации имело все свойства сущности из таблицы split, что делает его очень трудным для использования).