使用存储库模式时用于 Linq To SQL 的一个 DataContext

发布于 2024-12-29 07:20:05 字数 2154 浏览 1 评论 0原文

我对 .NET C# 开发相当陌生,最近开始使用 LINQ to SQL 来处理我的大部分数据访问层。不幸的是,我一直在努力解决如何管理我的 DataContext 的问题,这样我就不会遇到由于实体未附加到上下文或尝试将实体附加到一个上下文而同时附加到另一个上下文而导致的可怕异常。经过大量阅读后,我相信应用程序的最佳解决方案是在应用程序的整个持续时间内使 DataContext 保持打开状态。

简而言之,我使用存储库模式为我的上下文管理的所有实体实现基本的 CRUD 操作(即创建、读取、更新和销毁)。我对存储库的实现如下。除了存储库之外,我还为每个具有更具体数据访问方法的实体提供了 DAO(数据访问对象)(即 CustomerDAO.getCustomerByName(string name) 等)。我的每个 Windows 窗体都有自己的一个或多个 DAO 实例(扩展存储库),并且存储库中的 DataContext 是静态的。我遇到的问题是,即使下面的存储库类中的 DataContext 被声明为静态,我发现每个不同的 DAO 实际上都会获得不同的 DataContext 实例。例如,如果我有 8 个对 CustomerDAO 的引用,它们都具有相同的 DataContext。但是,如果我创建一个 WorkOrderDAO,我将获得 DataContext 的另一个实例,并且 WorkOrderDAO 的所有未来实例都会获得相同的 DataContext。更具体地说,我在以下场景中发现了这一点。

1) 使用 WorkOrderDAO 实例将所有 WorkOrder 加载到 ListView 中 - 有一个 DataContext 2) 使用 WorkOrderJobsDAO 的实例尝试删除 WorkOrder 上的作业之一。这是工单上的集合。有不同的 DataContext,所以我无法附加

这是我如何实现下面的存储库的问题吗?我能想到的解决这个问题的唯一方法是创建一个存储库用来获取其“DataContext”的单例。任何人都可以在这里就我应该如何管理上下文提出任何建议吗?

public class Repository<T> : IRepository<T>
where T : class
{
    private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    protected static DomainClassesDataContext db = new DomainClassesDataContext();
    private static bool dataContextOptionsInitialized = false;

    public Repository()
    {
        if (!dataContextOptionsInitialized)
        {
            db.DeferredLoadingEnabled = true;
            dataContextOptionsInitialized = true;
        }
    }
    public void AddEntity(T entity)
    {
        GetTable.InsertOnSubmit(entity);
        SaveAll();
    }

    public void DeleteEntity(T entity, bool attach)
    {
        if(attach)
            GetTable.Attach(entity);

        GetTable.DeleteOnSubmit(entity);
        SaveAll();

    }

    public void UpdateEntity(T entity, bool attach)
    {
        if(attach)
            GetTable.Attach(entity, true);
        SaveAll();

    }

    public System.Data.Linq.Table<T> GetTable
    {
        get { return db.GetTable<T>(); }
    }

    public IEnumerable<T> All()
    {
        return GetTable;
    }

    public void SaveAll()
    {
        db.SubmitChanges();

    }
}

I am fairly new to .NET C# development and recently started using LINQ to SQL for the majority of my data access layer. Unfortunately, I have been struggling with how to manage my DataContext so that I don't get the dreaded exceptions that result from entities either not being attached to a context or attempting to attach an entity to one context while it is attached to another. After much reading, I believe that the best solution for my application is to leave the DataContext open for the entire duration of my application.

In short, I am using the Repository pattern to implement the basic CRUD operations (i.e. Create, Read, Update, and Destroy) for all entities managed by my context. My implementation of the Repository is included below. In addition to the Repository, I have DAOs (Data Access Objects) for each entity that has more specific data access methods (i.e. CustomerDAO.getCustomerByName(string name), etc...). Each of my Windows forms has its' own instance of one or more DAOs (that extend Repository) and the DataContext in my repository is static. The problem that I am running into is that even though my DataContext in the repository class below is declared as static, I'm finding that each distinct DAO actually gets a different instance of the DataContext. For example, if I have 8 references to the CustomerDAO, they all have the same DataContext. But, if I create one WorkOrderDAO I get another instance of the DataContext and all future instances of WorkOrderDAO get this same DataContext. More specifically, I discovered this in the following scenario.

1) Use an instance of WorkOrderDAO to load all WorkOrders into ListView - Has one DataContext
2) Use an instance of WorkOrderJobsDAO to attempt to delete one of the jobs on the WorkOrder. This is a collection on the WorkOrder. Has a different DataContext so I can't attach

Is this a problem with how I have implemented the Repository below? The only thing that I can think of to solve this issue is to create a Singleton that the Repository uses to get its' DataContext. Can anyone make any recommendations here for how I should manage the Context?

public class Repository<T> : IRepository<T>
where T : class
{
    private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
    protected static DomainClassesDataContext db = new DomainClassesDataContext();
    private static bool dataContextOptionsInitialized = false;

    public Repository()
    {
        if (!dataContextOptionsInitialized)
        {
            db.DeferredLoadingEnabled = true;
            dataContextOptionsInitialized = true;
        }
    }
    public void AddEntity(T entity)
    {
        GetTable.InsertOnSubmit(entity);
        SaveAll();
    }

    public void DeleteEntity(T entity, bool attach)
    {
        if(attach)
            GetTable.Attach(entity);

        GetTable.DeleteOnSubmit(entity);
        SaveAll();

    }

    public void UpdateEntity(T entity, bool attach)
    {
        if(attach)
            GetTable.Attach(entity, true);
        SaveAll();

    }

    public System.Data.Linq.Table<T> GetTable
    {
        get { return db.GetTable<T>(); }
    }

    public IEnumerable<T> All()
    {
        return GetTable;
    }

    public void SaveAll()
    {
        db.SubmitChanges();

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紧拥背影 2025-01-05 07:20:05

C# 中的泛型类在编译时会“扩展”,因此您的存储库将是与存储库不同的类,这就是为什么静态变量在 DTO 之间是不同的实例。所以是的,您可能想将其保存在其他地方,例如 Singleton 类中的 a 。

Generic classes in C# gets "expanded" on compilation, so your Repository will be a different class than Repository, which is why the static variables are different instances between your DTOs. So yes you probably want to save it somewhere else, like a in a Singleton class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文