【问题标题】:C# LinqToSql LoadOption with pattern repositoryC# LinqToSql LoadOption 与模式存储库
【发布时间】:2021-12-30 08:33:50
【问题描述】:

在我正在维护的项目中,我使用存储库模式重构了一些逻辑,而不是旧的 ORM (LinqToSql)。

我现在的问题是有时我必须跨存储库共享 DataContext(这是一个理想的功能),但这些存储库试图“窃取”彼此的加载选项。

这是我的存储库构造函数的示例,它接收 DataContext 并构建正确的加载选项。

    public ArticleRepository(DataContext datacontext) : base(datacontext)
    {
        this.Name = "ArticleRepository";

        lock ( _sync )
        {
            this.Datacontext = datacontext; // --> this is done in base class, assing the shared object to the current repository.
            this.Datacontext.DeferredLoadingEnabled = false;

            DataLoadOptions options = new DataLoadOptions();
            options.LoadWith<tbl_ana_Article>(article => article.UoM);
            options.LoadWith<tbl_ana_Article>(article => article.Brand);
            this.Datacontext.LoadOptions = options;
        }
    }

但我也有 OrderRepository 它自己的加载选项。

当我在同一个 DataContext 上使用此类存储库时会出现问题:

using ( var context = new MyDatacontex("...") )
{
    var articleRepo = new ArticleRepository(context);
    var orderRepo = new OrderRepository(context);// <-- here the loading option are overwritten

    articleRepo.DoStuff();
    orderRepo.DoOtherStuff();

    context.SubmitChanges();
}

现在在这种特定情况下,我可以重新排序操作并避免出现问题,但这是一个非常具体且脆弱的解决方案。

我不知道是否必须在构造函数中指定加载选项,将其保存在对象中,并在每次使用(读取)数据上下文之前覆盖共享数据上下文属性。这是一个好的解决方案还是有更好的解决方案?

【问题讨论】:

  • 你有这样的麻烦应该告诉你你使用了错误的模式。该 DataContext 已经是一个工作单元,每个实体类型都有一个存储库成员。它缓存所有实体的所有更改,并在调用SubmityChanges 时将它们持久化。另一方面,LInq-to-SQL 不仅仅是旧的,它从来都不是一个功能齐全的 ORM。它很快被实体框架取代
  • those repository try to "steal" each other the loading option. 这些不是彼此的选择。它们适用于整个 DataContext。您正在尝试将低级别的单实体存储库包装器放在更高级别的多实体 DataContext 上。 DataContext 实例表示单个事务,仅加载和修改特定用例所需的实体。它不是整个数据库的模型,不应该尝试映射所有表。它只需要映射其特定用例所需的表。拥有不同实体的多个上下文非常好
  • @PanagiotisKanavos:如果我不理解,问题是我不应该有“共享边界”。每个域都有自己的存储库,具有自己的数据上下文,并且它们从不共享任何内容。问题是在我的场景中如此严格的建模风险(恕我直言)成本太高,所以我放松了一点。在某些情况下(像这样),处理运输的域必须与处理文章的域一起工作,因此它们可以一起工作,原子。让我知道我的图片是否有问题。再次感谢您的帮助,并为我的英语(不是母语)道歉
  • 错了。这里的域存储库是 DataContext 本身。如果您想使用领域驱动设计,DataContext 用于将实体持久保存在有界上下文中,用于加载聚合根。如果要抽象 DataContext,则需要创建一个存储库来处理整个有界上下文,而不是单个实体
  • @PanagiotisKanavos 啊..所以我有点失落抱歉。在我的想法中,我有许多 linq2sql 模型,每个域一个。文章和订单应该分开,但因为有时他们需要合作,我选择将它们放在同一个数据上下文中,即使它们有两个不同的存储库。通常文章和订单的存储库单独工作,但在需要时它们会合作(如在上传的代码中)。那时在我看来,将数据上下文视为域是一个好主意,因此我可以将加载选项都放在这个特定的数据上下文工厂中

标签: c# linq-to-sql datacontext


【解决方案1】:

由于Context是同一个对象,所以在使用前必须准备好。这是一个复杂的场景,因此在使用之前必须警告您“上下文选项”的状态。如果在特定用法之前更改它,则下一个用法必须清除最后一个选项或设置自己的选项。最好的方法可能是您在使用前设置选项并在使用后将其返回到以前的状态,这样一切都清楚了。但在异步场景中,您可能会看到出乎意料的行为。

另外一点,有些选项是共享的,有些不是。例如,DeferredLoadingEnabled 是共享设置,LoadWith 是特定选项。您可以决定在 Context 构造函数中固定共享设置并设置所有特定选项。

【讨论】:

  • 非常好的初始设置,我将在我的场景中调查可行性
猜你喜欢
  • 2013-10-07
  • 1970-01-01
  • 2020-09-10
  • 2010-09-22
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
相关资源
最近更新 更多