Примеры моделей.
public class Root
{
public string Id { get; private set; }
public ICollection<Child> Children { get; private set; }
}
public class Child
{
public string Id { get; private set; }
public string RootId { get; private set; }
public string Code { get; private set; }
public string Name { get; private set; }
}
Ограничения.
Ребенок имеет код RootId и свойство как его уникальный ключ.Это означает, что каждому корневому объекту разрешено иметь столько дочерних объектов, если только два или более дочерних объекта содержат один и тот же код.
Пример запроса
Получить все корневые записи с дочерним элементом, код которого равен A100.
Пример списка данных, содержащих два корневых объекта
Root1 with 2 children, one having a code A100 and the other A200.
Root2 with 2 children, one having a code A100 and the other A500.
Текущий запрос, которым я являюсьсейчас нужно получить все корневые записи вместе со всеми их детьми.Затем выполните итерацию каждой записи и удалите все ее дочерние элементы, у которых нет того же кода, который я запрашиваю.Проблема с этим подходом заключается в том, что при расширении базы данных он будет влиять на этот метод, поскольку я извлекаю всех дочерних элементов, когда все, что мне нужно, - это один для каждого корневого объекта.
Пример кода
var records = context.Roots
.Include(x => x.Children)
.Where(x => x.Children.Any(y => y.Code == "A100"))
.ToList();
foreach (var root in records)
{
foreach (var child in root.Children)
{
if (!child.Code == "A100")
{
root.Children.Remove(child);
}
}
}
В моих моделях установщики свойств настроены как частные в соответствии с принципами DDD.Поэтому я не могу выполнять проекции linq с помощью команды Select () , как показано ниже.
var records = context.Roots
.Include(x => x.Children)
.Where(x => x.Children.Any(y => y.Code == "A100"))
.Select(x => new Root{...})
.ToList();
Использование конструктора также не идеально в моем случае, потому что я устанавливаю состояние каждого объекта Создано во время создания как часть дизайна каждой модели.
Редактировать 1
Я мог бы использовать конструктор в проекции LINQ с помощью Select (), но моя проблема в том, что во всех моих моделях есть свойство, называемое Состояние , где я обновляюсь в разных точках моей модели в зависимости от того, что произошло.В части конструктора я обновляю его до состояния Create , чтобы подразумевать факт создания новой модели.Так что, если я собираюсь создать конструктор просто так, чтобы я мог создать экземпляр модели из базы данных, это привело бы к путанице, потому что я просто извлекаю уже существующую запись из базы данных, и если я собираюсь использовать конструктор,код, во время создания экземпляра помечает модель как Created , что не то, что я хочу, потому что это создаст новое значение в моем дизайне.
Edit 2
Мои извинения за то, что я недостаточно прояснил себя.Моя проблема в этой части запроса.
Часть 1.
var records = context.Roots
.Include(x => x.Children)
.Where(x => x.Children.Any(y => y.Code == "A100"))
.ToList();
Так что мне не нужно приходить на эту часть.
Часть 2
foreach (var root in records)
{
foreach (var child in root.Children)
{
if (!child.Code == "A100")
{
root.Children.Remove(child);
}
}
}
Теперь на основе упомянутых мною ограничений.
Ограничение 1. Не используется общедоступные сеттеры, поэтому я не могу использовать это.
var records = context.Roots
.Include(x => x.Children)
.Where(x => x.Children.Any(y => y.Code == "A100"))
.Select(x => new Root{...})
.ToList();
Constaint 2. Не используется конструктор
var records = context.Roots
.Include(x => x.Children)
.Where(x => x.Children.Any(y => y.Code == "A100"))
.Select(x => new Root(...))
.ToList();
Суть в том, есть ли запрос, который я могу использовать, или любой другой метод получения нужных мне записей прямо из базы данных без выполнениявторая часть запроса?