代码之家  ›  专栏  ›  技术社区  ›  Mike

混合ado.net和linq-to-sql是否不好?我的数据层不工作

  •  3
  • Mike  · 技术社区  · 16 年前

    更新

    正如Mathias在下面指出的那样,这里已经报告并解决了这个确切的问题: ASP.NET-MVC (IIS6) Error on high traffic: Specified cast is not valid

    原帖

    这可能是一个非常具体的调试问题,不能在这里发布,但是我无论如何都在发布它,希望它能产生一个其他人认为有用的解决方案。

    我有一个在中等负载下运行的Web应用程序——可能每秒5个请求。它有一些旧的代码通过ado.net+datareaders与SQL进行通信,并且已经使用这种技术至少五年了,没有问题。它还有一些使用linq to sql的更新代码。两种技术都使用相同的连接字符串来最大化连接池的重用。

    最近我经历了一个非常奇怪的行为,这些症状描述了:

    1. 一切都将在大约一天内正常工作,然后突然,对数据层(ADO.NET和LINQ)的每个调用(或几乎每个调用)都返回无法由代码解析的数据--我将得到异常,如“无法将”System.Int32“类型的对象强制转换为”System.String“类型。”或“序列不包含元素”或“indexOutOfRangeException”或“读卡器关闭时调用read的尝试无效”。

    2. 有趣的是,我从未从sqlcommand.executereader()或datareader.read()中获得异常——只有当我尝试分析返回的IDataRecord时才会出现异常。

    3. 我可以通过重新启动SQL或IIS临时解决此问题。几个小时后,它又回来了。

    4. 我尝试监视连接池中的连接数,但它从未超过3个。当然永远不会超过100。

    5. 我在事件日志中没有得到任何指示SQL或IIS有任何问题的信息。

    6. 驱动器有9 GB的空白空间。

    7. 我怀疑RAM有问题,但服务器使用的是注册的ECC DIMM。

    8. 我有其他使用ADO.NET的应用程序工作正常,而且从未出现问题。

    9. 当问题发生时,我可以通过ManagementStudio调用完全相同的存储过程,它们返回正确的预期结果。

    以下是我的ADO.NET访问模式:

    using (var dbConn = Database.Connection) // gets already-open connection
    {
      var cmd = new SqlCommand("GetData", dbConn);
      cmd.CommandType = CommandType.StoredProcedure;
      cmd.Parameters.AddWithValue("@id", id);
    
      SomeDataObject dataObject = null;
    
      var dr = cmd.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SingleRow);
    
      if (dr.Read())
        dataObject = new SomeDataObject(dr);
    
      dr.Close();
    
      return dataObject;
    }
    

    理论:代码的一部分使用ado.net,代码的另一部分使用linq(两者都使用来自连接池的相同连接),这有可能产生一些奇怪的副作用吗?

    问题:我应该尝试一些调试步骤吗?是否有可能有帮助的事件日志或性能指标?

    2 回复  |  直到 16 年前
        1
  •  1
  •   Community CDub    8 年前

    更新

    我在上面找到了一个明显有同样问题的人

    ASP.NET-MVC (IIS6) Error on high traffic: Specified cast is not valid .

    它在阿特尔的回答中得到了解释。

    原帖

    我在LinqToSQL应用程序中看到了加载时出现的问题。我使用了MVC-店面 RobConnery,所以我想很多人使用这种应用程序布局。 应用程序在小负载下工作得很好,但在这里,奇怪的错误听起来像是在中等负载下描述的错误。

    我怀疑这是数据库上下文存储位置的问题。

    在我的例子中,很容易复制:我使用JMeter,并且有5个线程,每个线程每秒有几个请求(我猜是20个)。我真的需要从多个线程开始加载。

    所以我的建议是:通过使用JMeter(不适合ASP.NET,但适合ASP.NET MVC)或Application Center测试创建一些负载,尝试在开发过程中重现错误。

        2
  •  2
  •   n8wrl    16 年前

    20+每秒5次点击的开放连接对我来说是一个红色标志。我们有接近100次点击/秒,并在10个连接上徘徊。

    记忆的使用呢?高吗?

    我怀疑你在释放资源方面有问题。我仍然对Linq to SQL很感兴趣,而且我对ADO.NET也有很长的积极经验。我想知道您是否缺少一个使用LinqToSQL清理连接等的模式。

    试试这个-你能把ADO.NET代码和应用程序中的LINQ隔离开来吗?如果您只进行ADO.NET调用,那么内存、连接计数等会发生什么情况?然后加入Linq的内容,看看它是如何影响它的。

    资源问题似乎“起步较晚”,因为它们需要一段时间积累。