Короткая версия:
Используя классический пример Order и OrderLine, как я могу сделать следующее в POCO:
public partial class Order {
public void RemoveInvalidOrderLines() {
OrderLines.Remove(OrderLines.Where(ol => ol.Quantity > MaxQuantity));
}
}
В отношении многие-к-одному, использующему POCO, это только удаляет ссылку на Заказ в OrderLine. Есть ли способ удалить сущность OrderLine автоматически? Или я должен внедрить хранилище или поднять код в службу? Использовать триггер в базе данных? Есть ли образец или лучшая практика для этого? Все примеры, которые я нахожу в Интернете, похоже, используют несколько простых дополнений и «Вот почему вы должны использовать POCO»: -)
Положение:
Используя EF4 CTP5 в VS2010, генерируя POCO, которые остаются невежественными (динамические прокси), я борюсь с тем, как обрабатывать удаление связанных «дочерних» сущностей.
Вопрос:
Метод Remove в ICollection Relative ниже в классе Employee удаляет только связь, но не конечную сущность. Есть ли способ заставить его также удалить сущность, не вводя хранилище / службу или не извлекая код из сущности? Я хочу чистый класс POCO.
Мотивация:
Относительная сущность не может существовать без сотрудника, поэтому наиболее естественным местом для обработки добавления, удаления и т. Д. Является класс Employee. Опять же, я открыт для предложений. : -)
Пример:
Один сотрудник может иметь много родственников. Существует класс репозитория для класса Employee, предоставляющий обычные средства поиска. Я бы хотел, чтобы сотрудник мог удалять родственников, а не только FK-отношения. Нужно ли вводить репозитории или подобное для этого? Я стараюсь держать контексты и репозитории вне POCO.
Допустим, следующие таблицы:
Employee:
Id int (PK, not null)
Name varchar
Relative:
Id int (PK, not null)
EmployeeId int (FK, not null)
Name varchar
Генерируются следующие POCO:
public partial class Employee {
...
public virtual ICollection<Relative> Relatives
{
get
{
if (_relatives == null)
{
var newCollection = new FixupCollection<Relative>();
newCollection.CollectionChanged += FixupRelatives;
_relatives = newCollection;
}
return _relatives;
}
set
{
if (!ReferenceEquals(_relatives, value))
{
var previousValue = _relatives as FixupCollection<Relative>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupRelatives;
}
_relatives = value;
var newValue = value as FixupCollection<Relative>;
if (newValue != null)
{
newValue.CollectionChanged += FixupRelatives;
}
}
}
}
И, конечно же,
Relative:
public partial class Relative {
...
public virtual Employee Employee
{
get { return _employee; }
set
{
if (!ReferenceEquals(_employee, value))
{
var previousValue = _employee;
_employee = value;
FixupEmployee(previousValue);
}
}
}
private Employee _employee;
}
Теперь можно сделать это:
var employeeRepository = new EmployeeRepository(dbContext);
var employee = employeeRepository.Get(1234);
var relative = new Relative { Name = "Lars" };
employee.Relatives.Add(relative);
context.SaveChanges();
и относительный элемент добавляется в таблицу «Относительный» и ссылается на сотрудника.
Однако, если я хочу реализовать метод DeleteRelative в классе Employee:
public void DeleteRelative(string name) {
Relatives.Remove(Relatives.FirstOrDefault());
}
(Наивный код, предполагающий наличие родственников и т. Д.)
Я получаю:
System.InvalidOperationException: The operation failed:
The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
Что вполне понятно, поскольку поле EmployeeId в Relative не может быть пустым.
Итак, опять же, возможно ли решить эту проблему каким-либо иным способом, кроме внедрения репозиториев / контекста в сущность (что, по-моему, противоречит цели POCO).
Другая альтернатива - это обернуть все это в сценарий службы или транзакции, но опять же, я бы хотел, чтобы EF4 справился с этим, не настраивая / не подключая сущности и не делая сценарии транзакции.
Любая помощь очень ценится, и если вам нужна дополнительная информация, скажите мне.
О, и счастливого нового года всем вам. : -)