删除存储库中的子实体

时间:2014-01-10 17:08:42

标签: c# ef-code-first domain-driven-design repository-pattern aggregateroot

我的应用程序为每个聚合根提供了一个存储库,但有时我只需要从这个聚合根中删除一个子实体。如何使用存储库模式执行此操作?

例如:

Brand (Aggregate Root)
|_ CarModels (Collection of CarModel)

我需要从品牌B中删除CarModel A,但我只有BrandRepository。那我怎么能实现这个呢?

我不知道我的代码是否会对您有所帮助,但现在是:

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();
}
}

缺少的一个信息是我首先使用的是EF代码。

2 个答案:

答案 0 :(得分:1)

我会使用Identifying Relationships实现这一点并对您的代码进行一些重构。

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; }
}

有许多方法可以实现存储库模式,并且我根据需要做了很少的更改,尽管我通常更喜欢在更高层中保存更改。

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();
    }

添加了一个测试,添加了两个车型的品牌,然后删除其中一个车型。

    [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);
        }
    }

答案 1 :(得分:1)

Brand brand = brandRepository.find(brandId);
brand.remove(carModelId);
brandRepository.save(brand);

但DDD似乎对显示数据有点过分。