1

我正在使用具有工作单元设计模式的实体框架和存储库。

有时,在我的工作单元中,我会向不同的服务发出其他调用。

该服务反过来创建自己的工作单元实例,例如:

ISettingsService settingsService = UnityContainer.Resolve<ISettingService>();
using (IUnitOfWork unitOfWork = UnitOfWorkFactory.CreateUnitOfWork())
{
    List<Company> companies = unitOfWork.CompaniesRepository.GetAll();
    foreach(Company company in companies)
    {
        settingsService.SaveSettings(company, "value to set");
        company.Processed = DateTime.UtcNow();
    }
    unitOfWork.Save();
}

// ISettingsService.SaveSettings code in another module...
ISettingsService.SaveSettings(Company company, string value)
{
    using (IUnitOfWork unitOfWork = UnitOfWorkFactory.CreateUnitOfWork())
    {
        Setting setting = new Setting();
        setting.CompanyID = company.CompanyID;
        setting.SettingValue = value;
        unitOfWork.Insert(setting);
        unitOfWork.Save();
    }
}

上面的代码确实有效,但我必须明确引用 ID 而不是附加公司对象(它会引发错误,因为它已经被其他服务中的其他工作单元跟踪)。

据我所知,我看到了 3 种发生这种情况的方式:

1)按原样使用代码,服务层创建自己的工作单元实例,对其他实体的任何其他引用都是在主键基础上完成的(设置值的过程应该由主键对象值传递,即 int客户ID)。

不利的一面是对数据库的潜在影响更大,如果实体主键类型发生更改,我将需要更改 ID 字段的所有服务层引用。__

2) 让服务层接受实体对象作为参考。这会很好,因为我可以传递对象。

不利的一面是实体不得从任何其他上下文中引用,并且必须附加到将要使用它的上下文中。在一个循环中,实体很可能已经被附加。__

3) 将工作单元实例化传递给其他服务层,以便他们可以使用现有的工作单元而不是实例化自己的工作单元。

除了必须传递工作单元引用之外,不确定这是否有不利之处,好处是能够引用对象而无需附加它们或担心它们是否已经附加。__

总之,我需要对一种访问设计进行标准化,并希望就我应该选择哪种访问设计提出建议。

此外,还有什么我需要关注的事务,或者是具有工作单元设计模式的 EntityFramework 隐式地实现了一种事务处理形式,因为更改仅在 context.Save() 上提交,还是我弄错了?

谢谢,

克里斯

4

1 回答 1

1

您有几个选择:

  1. 让不同的服务传递分离的实体(它的实体),甚至可能是不是实体的 DTO,然后让每个服务将它们转换为它的实体(或使用主键)。

    每个服务都可以创建自己的内容并使用自己的 EDMX 或共享的 EMDX(甚至多个 EDMX)。

  2. 如果服务使用相同的 EDMX,则将相同的上下文注入它们(您可以将其包装在后面并进行接口,以便它们不会暴露 EF)。

  3. 如果服务不使用相同的 EDMX,则:

    3.1。选择选项 1,为不同的服务(或 DTO)使用不同的实体。

    您可以使用不同实体在 EDMX 之间“共享”表,或使用视图“来自外部域的表”以将只读版本的表反映到其他域。

    3.2. 通过将 EDMX 合并为一个大的来创建主 EDMX(有关详细信息,请参阅此问题

更改仅在调用 context.AcceptChanges() 时应用,因此您可以将更改保存到多个上下文,然后在所有保存完成后接受每个上下文中的更改。

于 2012-06-05T19:26:23.613 回答