Очевидно, что CurrentContext
- это Dbcontext
с хотя бы таблицей SystemAreas
и таблицей SystemAreaFunctionalities
.
Кажется, что каждый SystemArea
имеет ноль или более SystemAreaFunctionalities
;каждый SystemAreaFunctionality
принадлежит ровно одному SystemArea
, прямому отношению один-ко-многим с использованием внешнего ключа.
Примечание: может случиться так, что у вас есть отношение ко многим, ответ будетбыть похожим
Увы, вы забыли написать свои классы, поэтому я сделаю снимок:
class SystemArea
{
public int Id {get; set;}
... // other properties
// every SystemArea has zero or more SystemAreaFunctionalities (one-to-many)
public virtual ICollection<SystemAreaFunctionality> SystemAreaFunctionalities {get; set;}
}
class SystemAreaFunctionality
{
public int Id {get; set;}
... // other properties
// every SystemAreaFunctionality belongs to exactly one SystemArea, using foreign key
public int SystemAreaId {get; set;}
public virtual SystemArea SystemArea {get; set;}
}
В структуре сущностей столбцы ваших таблиц представлены не виртуальнымисвойства, виртуальные свойства представляют отношения между таблицами.(один ко многим, много ко многим, ...)
для полноты:
class CurrentContext : DbContext
{
public DbSet<SystemArea> SystemAreas {get; set;}
public DbSet<SystemAreaFunctionality> SystemAreaFunctionalities {get; set;}
}
Если людям нужны элементы со своими подпунктами, например Schools
с их Students
, Customers
с их Orders
и т. Д. Люди склонны выполнять (group)Join
.Однако при использовании сущностных каркасов соединения редко необходимы.Вместо этого используйте ICollections.Платформа сущностей знает отношения и знает, какую (группу) объединить для выполнения.
Регулярно я вижу, что люди используют Include
, но если вы сделаете это, вы выберете полный объект, что не очень эффективно.Предположим, у вас есть SystemArea
с Id = 10 и 1000 SystemAreaFunctionalities
, вы знаете, что каждый SystemAreaFunctionality
имеет внешний ключ SystemAreaId
со значением 10. Вместо того, чтобы отправлять это значение только один раз в качестве первичного ключа SystemArea
, Include
также выберет все 1000 внешних ключей с этим значением 10. Какая трата вычислительной мощности!
При запросе данных всегда используйте Select и выбирайте только те свойства, которые вы фактически планируете использовать,Используйте «Включить», только если вы планируете обновить включенный объект.
Вы писали:
SystemAreaFunctionality - это дочерний объект, который я пытаюсь преобразовать здесь ...
Не понятно, чего вы действительно хотите.Вы хотите получить коллекцию всех используемых SystemAreaCodes?Или вы действительно хотите коллекцию новых SystemAreaFunctionalities, где заполнено только одно поле: SystemAreaCode?Из-за того, что вы используете единственное имя свойства, кажется, вы не хотите коллекцию, а только один элемент.
var result = currentContext.SystemAreas.Select(systemArea => new
{
Id = systemArea.Id,
Code = systemArea.Code,
...
// if you want a collection of SystemAreaFunctionalities
// where every SystemAreaFunctionality is filled with only SysemAreaCode
// do the following:
SystemAreaFunctionalities = systemArea.SystemAreaFunctionalities
.Select(systemAreaFunctionality => new SystemAreFunctionality
{
SystemAreaCode = systemAreaFunctionality.SystemAreaCode,
})
.ToList(), // DON'T FORGET THIS, OR YOU WON'T GET RESULTS!
})
.ToList()
}
Я думаю, что причина ваших пустых SystemAreaFunctionalities заключается в том, что вы забыли сделать ToList().
Поскольку вы использовали ToList (), у вас автоматически будет счетчик выбранных функций SystemAreaFunctionalities.Нет необходимости выбирать этот счетчик отдельно.
Одна из более медленных частей запросов к базе данных - это передача выбранных данных из системы управления базами данных в локальный процесс.Рекомендуется выбирать только те данные, которые вы действительно планируете использовать
Ваш запрос не очень эффективен, поскольку вы выбираете полные SystemAreaFunctionalities и заполняете только SystemAreaCode.Все остальные поля будут заполнены значениями по умолчанию.Помимо более медленного запроса, у ваших абонентов также создается впечатление, что они правильно заполнены SystemAreaFunctionalities.Улучшенная версия будет выглядеть так:
var result = currentContext.SystemAreas.Select(systemArea => new
{
// select only the properties you actually plan to use
Id = systemArea.Id,
Code = systemArea.Code,
...
// if you only need the SystemAreaCodes, select only that property
SystemAreaCodes = systemArea.SystemAreaFunctionalities
.Select(systemAreaFunctionality => systemAreaFunctionality.SystemAreaCode)
.ToList(),
})
.ToList()
};
Конечно, если вам нужно больше, чем просто SystemAreaCodes, но несколько SystemAreaFunctionalities, выберите их:
...
SystemAreaFunctionalities = systemArea.SystemAreaFunctionalities
.Select(systemAreaFunctionality => new
{
// again: select only the properties you plan to use!
Id = systemAreaFunctionality.Id
SystemAreaCode = systemAreaFunctionality.SystemAreaCode,
})