Я подозреваю, что вы, возможно, неправильно используете .Select
, потому что это именно то, для чего он предназначен.
Чтобы получить соответствующие данные A, без B или C:
var aDetails = context.As.Select(a => new { a.Id, a.Name }).ToList();
Обратите внимание, что при этом возвращается анонимный тип, содержащий только те поля, которые вы хотите, в данном случае идентификатор и имя из записей A. Теперь, если вы хотите вернуть эти данные для использования в представлении и т. Д., Вы можете определить класс модели представления с именем AViewModel, например, с этим идентификатором и именем:
var viewModels = context.As.Select(a => new AViewModel{ Id = a.Id, Name = a.Name }).ToList();
Часто люди попадают в ловушку, пытаясь отправить объекты в представление. Это плохой, плохой шаблон, который слишком часто застекляется ради того, чтобы избежать определения другого класса POCO, который очень похож на сущность. Однако есть две действительно веские причины, по которым вам следует избегать этого: безопасность информации и производительность. (Обрисовано в общих чертах здесь ) Если вы делаете что-то вроде:
var results = context.As.ToList();
или даже
var results = context.As.Select(a => a).ToList();
При включенном LazyLoading (EF6) Это загрузит только ваши записи A без B или C. Однако, если вы попытаетесь передать эти объекты обратно вашему клиенту, сериализатор будет выполнять итерацию по каждому свойству, отключая ленивую загрузку в коллекциях B и C, загружая каждый набор для каждой отдельной записи A. При возврате коллекции A это будет намного, гораздо хуже, чем если бы вы с нетерпением загрузили B и C в своем запросе, потому что, если вы возвращаете записи 5x A, ленивые вызовы загрузки составят:
ВЫБРАТЬ ИЗ B, ГДЕ AId = 1, ВЫБРАТЬ ИЗ B, ГДЕ AId = 2, ...
ВЫБРАТЬ ИЗ C, ГДЕ AId = 1, ВЫБРАТЬ ИЗ C, ГДЕ AId = 2, ...
10x дополнительных операторов SQL вместо включения всех связанных строк B и C в один начальный (больший) оператор SQL. Вы можете избежать этой ловушки производительности, отключив ленивую загрузку EF (отключив прокси), но тогда у вас останутся пустые коллекции, которые не отражают ваше реальное состояние данных. (ИМО объект должен всегда полностью представлять свое состояние данных, не догадываясь, просто ли отсутствующие данные не были загружены, или объект фактически не имеет связанных данных.)
Чтобы узнать, как Select
может улучшить производительность; Допустим, у вас есть набор заказов, в котором есть список позиций заказа, и каждый заказ связан с клиентом. Требуется номер заказа, общая стоимость элементов заказа и имя клиента. Вы не хотите загружать все позиции заказа и данные клиента для каждого заказа:
var orderDetails = context.Orders
.Where(o => o.OrderDate >= startDate && o.OrderDate < endDate)
.Select(o => new OrderViewModel
{
OrderId = o.OrderId,
OrderNumber = o.OrderNumber,
CustomerName = o.Customer.FullName,
Total = o.OrderLines.Sum(ol => ol.UnitPrice * ol.Quantity)
}).ToList();
Это мощная функция EF и Linq, которая помогает гарантировать, что база данных выполняет большую часть работы и возвращает только те поля, которые вам понадобятся. Меньше данных по проводам, меньше памяти на сервере приложений и клиенте.