带有 LINQ 2 SQL 连接的 Windows 服务的 C# 设计数据访问

Posted

技术标签:

【中文标题】带有 LINQ 2 SQL 连接的 Windows 服务的 C# 设计数据访问【英文标题】:C# Design Data Access for Windows Service with LINQ 2 SQL connection 【发布时间】:2014-08-16 03:01:15 【问题描述】:

我有一个类库设置,它是我们使用 LINQ 2 SQL 的数据访问。它正在使用存储库模式。

我们的 Repository 类有一个基类,它具有我们的 DB 上下文:

    private DataDB db = null;
    public DataDB DBContext
    
        get
        
            if (db == null)
                db = new DataDB(ConnectionString);
            return db;
        
    

使用 Structure Map DI,我们将 Repository 类注入到我们的服务中。

我看到的问题是我们有大量无法访问数据的常规类。我们为缓解这种情况所做的工作(我不确定这是否正确)是我们有 DI Factory 助手类,它在调用时实例化服务/repo:

public static class DIFactory

    #region Services

    public static IDataService DataService
    
        get
        
            return ObjectFactory.GetInstance(typeof(IDataService)) as IDataService;
        
    

    #endregion    

    #region Repositories

    public static IRepository Repository
    
        get
        
            return ObjectFactory.GetInstance(typeof(IRepository)) as IRepository;
        
    

    #endregion

当向服务推送请求(通常是高负载)时遇到的问题,我们看到如下 DB 错误:

Exception: SyncMethodInvoker.Invoke =>  E[Invalid attempt to call MetaData when reader is closed.
[There is already an open DataReader associated with this Command which must be closed first.]
[Invalid attempt to call MetaData when reader is closed.]

【问题讨论】:

【参考方案1】:

我遇到了类似的问题,它与迭代查询结果有关。确保任何时候你在迭代 IEnumerable 的东西时都先执行 ToArray()

// Don't do
foreach(var x in items.Where(i => i.value == true))
...

// Do
foreach(var x in items.Where(i => i.value == true).ToArray())
...

【讨论】:

以上是关于带有 LINQ 2 SQL 连接的 Windows 服务的 C# 设计数据访问的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有内连接的 sql 查询转换为 linq lambda 表达式?

带有表连接、case 语句、计数、group by 子句的 Linq 查询

带有自定义比较器的 Linq 左外连接

.NET / LINQ-SQL / ASP.NET 中的连接字符串地狱

如何使用 linq lambda 扩展方法执行带有 where 子句的左外连接

在 WP7 上通过 Linq 2 SQL 存储拉丁字符