Как обновить сущность внутри агрегата
У меня есть агрегат с именем Campaign, каждый с корневым объектом с именем Campaign, этот корневой объект имеет список попыток (объект)
public class Attempts: IEntity<Attempts>
{
private int id;
public AttempNumber AttemptNumber {get;}
//other fields
}
public class Campaign: IEntity<Campaign> //root
{
private int id;
public IList<Attempt> {get;}
//other fields
}
Я использую метод, чтобы добавить попытку кампании
public virtual void AssignAttempts(Attempts att)
{
Validate.NotNull(att, "attemps are required for assignment");
this.attempts.add(att);
}
Проблема возникает, когда я пытаюсь редактировать определенный элемент в списке попыток. Я получаю Attempt от AttempNumber и передаю его методу editAttempt, но я не знаю, как установить попытку, не удаляя весь список, и воссоздать его снова.
public virtual void EditAttempts(Attempts att)
{
Validate.NotNull(att, "attemps are required for assignment");
}
Любая помощь будет оценена!
Спасибо, Педро де ла Круз
2 ответа
Во-первых, я думаю, что может быть небольшая проблема с вашей моделью домена. Мне кажется, что "Кампания" должна быть совокупной корневой сущностью, имеющей коллекцию объектов (или сущностей) значения "Попытка". Агрегат "Кампании" не существует, если у вас нет родительской концепции для кампании, которая будет содержать набор кампаний. Также нет объекта "Попытки". Вместо этого коллекция сущностей "Попытка" или значений в сущности "Кампания". "Попытка" может быть сущностью, если она имеет идентичность за пределами "Кампании", в противном случае это объект значения. Код может выглядеть примерно так:
class Campaign {
public string Id { get; set; }
public ICollection<Attempt> Attempts { get; private set; }
public Attempt GetAttempt(string id) {
return this.Attempts.FirstOrDefault(x => x.Number == id);
}
}
class Attempt {
public string Number { get; set; }
public string Attribute1 { get; set; }
}
Если вы извлекаете Попытку из сущности Campaign, а затем изменяете некоторые свойства, вам не нужно вставлять ее обратно в сущность кампании, она уже там. Вот как будет выглядеть код, если вы используете NHibernate (аналогично для других ORM):
var campaign = this.Session.Get<Campaign>("some-id");
var attempt = campaign.GetAttempt("some-attempt-id");
attempt.Attribute1 = "some new value";
this.Session.Flush(); // will commit changes made to Attempt
Вам не нужен метод редактирования. Ваш код может изменить Попытки на месте, например так:
Attempt toModify = MyRepository.GetAttemptById(id);
toModify.Counter++;
toModify.Location = "Paris";
MyRepository.SaveChanges(); // to actually persist to the DB
Конечно, как вы называете SaveChanges(), зависит от вас, так Entity Framework называет свой общий метод Save.