Через различные вопросы я спросил здесь и другие форумы, я пришел к выводу, что понятия не имею, что я делаю когда дело доходит до сгенерированных объектов контекста объекта в Платформе Объекта.
Как фон, у меня есть тонна опыта с помощью LLBLGen Pro, и Платформе Объекта приблизительно три недели мне.
Позволяет говорят, что у меня есть контекст, названный "myContext". Существует таблица/объект под названием Сотрудник в моей модели, таким образом, у меня теперь есть myContext. Сотрудники. Я предполагаю, что это означает, что это свойство представляет набор объектов Сотрудника в моем контексте. Однако я принимаю неправильно, поскольку я могу добавить новый объект к контексту с:
myContext.Employees.AddObject(new Employee());
и этот новый объект Сотрудника не появляется нигде в myContext. Сотрудники. Из того, что я собираюсь, единственный способ найти, что этот недавно добавленный объект должен отследить его вниз скрывающийся в myContext. ObjectStateManager. Это звучит мне как myContext. Сотрудники устанавливают, на самом деле не набор объектов Сотрудника в контексте, а скорее некоторое представление объектов Сотрудника, которые существуют в базе данных.
Для добавления далее к этому беспорядку, Позволяет, говорят, что я смотрю на единственный объект Сотрудника. Существует объект Проекта, который имеет отношения M:1 с Сотрудником (у сотрудника может быть несколько проектов). Если я хочу добавить новый проект к конкретному сотруднику, я просто делаю:
myEmployee.Projects.Add(new Project());
Большой, это на самом деле добавляет Проект к набору, как я ожидал бы. Но это летит прямо перед лицом того, как свойства ObjectSet прочь контекста работают. Если я добавляю новый Проект к контексту с:
myContext.Projects.AddObject(new Project());
это не изменяется, Проекты устанавливают.
Я ценил бы его очень, если бы кто-то должен был объяснить это мне. Кроме того, я действительно хочу набор всех Сотрудников (или Проекты) в контексте, и я хочу его доступный как свойство контекста. Действительно ли это возможно с EF?
ObjectSet
- это запрос. Как и все в LINQ, это лениво. Он ничего не делает, пока вы не перечислите его или не вызовете такой метод, как .Count ()
, после чего будет запущен запрос к базе данных, и все возвращенные объекты не будут объединены с теми, которые уже находятся в контексте.
Таким образом, вы можете сделать что-то вроде:
var activeEmployees = Context.Employees.Where(e => e.IsActive)
... без выполнения запроса.
Вы можете дополнительно составить это:
var orderedEmployees = activeEmployees.OrderBy(e => e.Name);
... снова без выполнения запроса.
Но если вы посмотрите на набор:
var first = orderedEmployees.First();
... то будет выполнен запрос к БД. Это общее для всех LINQ.
Если вы хотите перечислить объекты, уже находящиеся в контексте, вам нужно вместо этого обратиться к ObjectStateManager
. Итак, для Сотрудников вы можете делать:
var states = EntityState.Added || EntityState.Deleted || // whatever you need
var emps = Context.ObjectStateManager.GetObjectStateEntries(states)
.Select(e => e.Entity)
.OfType<Employee>();
Обратите внимание, что, хотя это работает, я не рекомендовал бы работать таким способом. Как правило, вы не хотите, чтобы ваши ObjectContexts были долговечными. По этой и другим причинам они не совсем подходят для использования в качестве универсального контейнера объектов. Используйте для этого обычные типы списков. Точнее рассматривать ObjectContext как единицу работы. Обычно в единице работы вы уже знаете, с какими экземплярами вы работаете.