Reputation: 8177
My applications has a repository for each aggregate root, but sometimes I need to remove only one child entity from this aggregate root. How can I do this with the repository pattern?
Ex:
Brand (Aggregate Root) |_ CarModels (Collection of CarModel)
I need to remove CarModel A from the brand B, however I only have BrandRepository. So how can I achieve this?
I don't know if my code will help you, but here it is:
public class Brand
{
public int Id {get;set;}
public string Name {get;set;}
public virtual ICollection<CarModel> Models {get;set;}
}
public class CarModel
{
public int id {get;set;}
public string Name {get;set;}
}
public class BrandRepository
{
/// ....
public void Save(Brand entity)
{
this.context.Brands.AddOrUpdate(entity);
this.context.SaveChanges();
}
public void Delete(Brand entity)
{
this.context.Brands.Remove(entity);
this.context.SaveChanges();
}
}
One information that was missing is that I'm using EF code-first.
Upvotes: 1
Views: 1430
Reputation: 7283
Brand brand = brandRepository.find(brandId);
brand.remove(carModelId);
brandRepository.save(brand);
But DDD seems to be an overkill for displaying data.
Upvotes: 1
Reputation: 2876
I would implement this using Identifying Relationships and a little refactoring of your code.
public class CarModel
{
[Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
[Key, ForeignKey("Brand"), Column(Order=1)]
public int BrandId { get; set; }
public Brand Brand { get; set; }
}
There are numerous ways to implement the repository pattern and I made as little changes as necessary, although I normally prefer to save changes in a layer higher up.
public class BrandRepository
{
private readonly Context context;
public BrandRepository(Context context)
{
this.context = context;
}
public void Add(Brand brand)
{
this.context.Brands.Add(brand);
}
public Brand FindByName(string name)
{
return this.context.Brands.Single(b => b.Name == name);
}
public void RemoveCarModel(Brand brand, string carModelName)
{
var carModelToRemove = brand.Models.Single(cm => cm.Name == "A car model");
brand.Models.Remove(carModelToRemove);
}
public void Save()
{
context.SaveChanges();
}
Added a test that adds a brand with two car models and then removes one of the car models.
[TestMethod]
public void Test()
{
// Arrange.
using (var context = new Context())
{
var models = new List<CarModel> {
new CarModel { Name = "A car model" },
new CarModel { Name = "Another car model" }
};
var brand = new Brand { Name = "A Brand", Models = models };
var brandRepository = new BrandRepository(context);
brandRepository.Add(brand);
brandRepository.Save();
}
// Act.
using (var context = new Context())
{
var brandRepository = new BrandRepository(context);
var brand = brandRepository.FindByName("A brand");
brandRepository.RemoveCarModel(brand, "A car model");
brandRepository.Save();
}
// Assert.
using (var context = new Context())
{
var brandRepository = new BrandRepository(context);
var brand = brandRepository.FindByName("A brand");
Assert.AreEqual(1, brand.Models.Count);
Assert.AreEqual("Another car model", brand.Models.Single().Name);
}
}
Upvotes: 1