Nano Hash - криптовалюты, майнинг, программирование

Автоматически включать свойства Entity Framework

ответ на мой вопрос может быть тривиальным, но я не могу понять, как это сделать.

Допустим, у нас есть следующая ситуация:

Первая EF-сущность БД с вложенными свойствами:

public partial class Employee
{
     public int ID { get; set;}
     public virtual ICollection<EmployeeDepartmentHistory> EmployeeDepartmentHistory { get; set;}
     public virtual ICollection<JobCandidate> JobCandidate { get; set;}
}

Доменный класс Employee

(связанные классы не имеют значения для этого примера)

public class Employee
{
     public int ID { get; set;}
     public IEnumerable<Department> Departments { get; set;}
     public IEnumerable<JobCandidate> Candidates { get; set;}
}

Класс обслуживания EmployeeService, который применяет бизнес-правила к запросу.

public class EmployeeService
    private RepoTestEntities1 _Database;

    public EmployeeService(RepoTestEntities1 database)
    {
        _Database = database;
    }

    public IQueryable<DomainModels.Employee> GetSalariedEmployeesByDepartmentName(string departmentName)
    {
        _Database.Configuration.LazyLoadingEnabled = false;
        return _Database.Employee
            .Include(e => e.EmployeeDepartmentHistory)
            .Include(e => e.JobCandidate)
            .Include(e => e.EmployeeDepartmentHistory.Select(his => his.Department))
            .AsNoTracking()
            .WhereDepartmentName(departmentName)
            .WhereSalariedFlag(true)
            .Select(e => CreateEmployee(e));
    }
    private DomainModels.Employee CreateEmployee(Employee e)
    {
        [...] (transform to domain)
    }

WhereDepartmentName и WhereSalariedFlag реализованы как методы расширения для IQueryable<Employee>.

Теперь к вопросу


Предположим, мне нужны дополнительные методы, которые извлекают сотрудников из DbContext, и я не хочу использовать отложенную загрузку.

Неоднократный вызов всех этих включений является избыточным, подверженным ошибкам и утомительным. Знаете ли вы элегантный способ всегда включать необходимые свойства для всех методов EmployeeService?

Может ли шаблон стратегии быть жизнеспособным подходом?


  • Нет, не делай этого. Не включайте в свои объекты все свои навигационные свойства. Просто получите то, что хотите. Если это опасение подверженности ошибкам, просто протестируйте все реализованные методы. 22.05.2018
  • Вы можете создать метод расширения или использовать automapper: codereview.stackexchange.com / questions / 30839 / 22.05.2018
  • Вы также можете предоставить различные свойства, которые просто возвращают DbSet со всеми включениями. Однако, как упоминалось в @CodeNotFound, загрузка всех свойств навигации обычно сильно снижает производительность и может сделать ваш BL более подверженным ошибкам. 22.05.2018
  • Предпочитайте явную загрузку ленивой загрузке. 22.05.2018
  • @CodeNotFound и DevilSuichiro: Поскольку я каким-либо образом консолидирую связанные объекты в доменном классе, я не думаю, что это снижает производительность. Особенно, если вместо первоначальной загрузки свойств навигации я лениво загружаю все связанные свойства сами по себе, что означает попадание db в каждое свойство. Почему это сделает мой BL более подверженным ошибкам?!. Комментарий Стива Гринса указывает правильное направление. 22.05.2018
  • Вы можете написать расширение, которое будет включать все свойства, которые ICollection<> передают имя свойства вместо лямбда-аксессора. Однако, как предполагали другие, это может вызвать серьезные проблемы с производительностью, которые могут вызвать появление седых волос, поэтому я буду использовать его с осторожностью. 23.05.2018

Ответы:


1

Если вам ДЕЙСТВИТЕЛЬНО нужно включить все свойства навигации, вы можете использовать этот фрагмент кода.
Если вам нужно быстро загрузить также коллекции (не всегда хорошая идея), вы можете удалить оператор continue в коде.
Контекст это ваш контекст (this, если вы вставляете этот код в свой контекст)

    public IQueryable<T> IncludeAllNavigationProperties<T>(IQueryable<T> queryable)
    {
        if (queryable == null)
            throw new ArgumentNullException("queryable");

        ObjectContext objectContext = ((IObjectContextAdapter)Context).ObjectContext;
        var metadataWorkspace = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace();

        EntitySetMapping[] entitySetMappingCollection = metadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().EntitySetMappings.ToArray();

        var entitySetMappings = entitySetMappingCollection.First(o => o.EntityTypeMappings.Select(e => e.EntityType.Name).Contains(typeof(T).Name));

        var entityTypeMapping = entitySetMappings.EntityTypeMappings[0];

        foreach (var navigationProperty in entityTypeMapping.EntityType.NavigationProperties)
        {
            PropertyInfo propertyInfo = typeof(T).GetProperty(navigationProperty.Name);
            if (propertyInfo == null)
                throw new InvalidOperationException("propertyInfo == null");
            if (typeof(System.Collections.IEnumerable).IsAssignableFrom(propertyInfo.PropertyType))
                continue;

            queryable = queryable.Include(navigationProperty.Name);
        }

        return queryable;
    }
19.11.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..