【问题标题】:Delete child entities in a repository删除存储库中的子实体
【发布时间】:2014-01-10 17:08:41
【问题描述】:

我的应用程序对每个聚合根都有一个存储库,但有时我只需要从这个聚合根中删除一个子实体。如何使用存储库模式做到这一点?

例如:

品牌(总根) |_ CarModels(汽车模型集合)

我需要从品牌 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 代码优先。

【问题讨论】:

  • 这是具体实现的问题。因此,如果没有代码,您的问题毫无意义。
  • 为问题添加了更多细节。
  • @JulianoNunesSilvaOliveira,您选择了哪种解决方案?请接受答案。

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


【解决方案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);
        }
    }

【讨论】:

    【解决方案2】:
    Brand brand = brandRepository.find(brandId);
    brand.remove(carModelId);
    brandRepository.save(brand);
    

    但 DDD 似乎在显示数据方面有点过头了。

    【讨论】:

    • 我的实体是 POCO。它们没有任何操作,只有属性。
    • @JulianoNunesSilvaOliveira 那么为什么要使用 DDD 和存储库模式呢?
    • 我不明白你为什么要问这个。
    • 如果您的实体是 POCO,那么它不是 DDD,而是 Anemic Domain Model,这被认为是一种反模式。
    • @JulianoNunesSilvaOliveira 我不认为贫血域模型是一种反模式,它在大多数项目中运行良好。但这种架构风格通常不会与 DDD 齐头并进。
    猜你喜欢
    • 2022-01-25
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多