解决方案 »
- .cs 自动加载了using System.linq 等,要怎么设定加载哪些
- 请教大家一个关于NET生成动态JS数组的问题
- 无法找到xml节点
- 上传附件,求帮忙!
- 这个问题,我实在是百思不得其解...希望有高人可以指点
- +++++++++++++++++++++++一个js问题++++++++++++++++++++++++
- forms权限验证的问题,指教
- 一个产品信息第一页列表,第二页详细信息,第一页链接写好了,第二页怎么写?
- textbox内只能输入数字和字符的正则表达式怎么写啊
- 小弟作了一个上传下载的程序,作完之后发现了问题,上传一个文件,如果太大,很慢,应为我采用的是http协议,能不能享邮件的附件的方式,
- 自定义的可输入下拉框控件,下拉框数据状态保持问题
- asp.net 用户信息修改 textbox数据库绑定!在线求高手帮忙!!^^
另外,提示datareader没有关闭,是否与你的方法是静态的有关系?建议尽量少使用静态调用!
如果大数据量 最后一页读取的时候 都会很慢的吧
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;
using 的应该是 connection
http://www.cnblogs.com/wlb/archive/2012/04/08/2437617.html还有你确定你的那个DbDataReader实现了IDispose这个接口了吗?
using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
//rd.Close();
rd.dispose()//试试
return dt;
DbDataReader 是在这个命名空间下的System.Data.Common
using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection)) if (cmd.Connection.State == ConnectionState.Open)
cmd.Connection.Close();
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;我手动插入红色的部分 冒失 就不会提示这个错误
但是静态成员估计会有问题吧。
现在分页都有弊端,页数越大,效率越低下。把DataReader改成DataSet,
DataReader 和 DataSet 最大的区别在于,DataReader 使用时始终占用 SqlConnection,在线操作数据库..任何对 SqlConnection 的操作都会引发 DataReader 的异常..因为 DataReader 每次只在内存中加载一条数据,所以占用 的内存是很小的..因为 DataReader 的特殊性和高性能.所以 DataReader 是只是 向前读的 读了第一条后就不能再去读取第一条了 dataSet 则是将数据一次性加 载在内存中.抛弃数据库连接读取完毕即放弃数据库连接因为 DataSet 将数据全 部加载在内存中.所以比较消耗内存但是确比 DataReader 要灵活
是的 数据量会很大 采用dataset的话 会很 吃内存 暂不考虑
using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;你的连接最好是手动关闭
而且连接不要是单例(静态的)的
CommandBehavior.CloseConnection:虽然表示关闭read时关闭连接。但是C#不会即使关闭的
try
{
DataTable dt = null;
using (DbDataReader rd = cmd.ExecuteReader())
{
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn; rd = cmd.ExecuteReader();
dt = new DataTable();
dt.Load(rd);
rd.Close();
}
}
catch
{
throw;
}
finally
{
cmd.Connection.Close();
}
return dt;
学习中[color]
重构一下你的底层的Sql访问吧using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt; using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Common;
using System.Data;
using System.Web;namespace AnNet.Entity
{
internal abstract class DbSqlHelper : ISqlHelper
{
/// <summary>
/// 事务对象
/// </summary>
private DbTransaction transaction; /// <summary>
/// 结果集
/// </summary>
private DbDataReader reader;
/// <summary>
/// 当前连接对象
/// </summary>
protected DbConnection connection; /// <summary>
/// 执行对象
/// </summary>
protected DbCommand command; /// <summary>
/// 获取DbDataAdapter
/// </summary>
protected DbDataAdapter dataAdapter;
/// <summary>
/// 创建连接对象
/// </summary>
/// <returns>创建的连接</returns>
protected abstract DbConnection CreateConnection(string connectionString); /// <summary>
/// 创建DataAdapter对象
/// </summary>
/// <returns>创建的DataAdapter对象</returns>
protected abstract DbDataAdapter CreateDataAdapter(); /// <summary>
/// 构造对象实例
/// </summary>
public DbSqlHelper(string connectionString)
{
this.connection = this.CreateConnection(connectionString);
this.command = this.connection.CreateCommand();
this.dataAdapter = this.CreateDataAdapter();
} /// <summary>
/// 获取当前的连接对象
/// </summary>
public DbConnection Connection
{
get { return connection; }
} /// <summary>
/// 执行SQL语句返回受影响的行数
/// </summary>
/// <param name="cmdType">语句类型</param>
/// <param name="cmdText">SQL语句</param>
/// <returns>受影响的行数</returns>
public int ExecuteNonQuery(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
{
int val = 0;
this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
val = this.command.ExecuteNonQuery();
this.command.Parameters.Clear();
return val;
}
/// <summary>
/// 执行SQL语句返回记录集
/// </summary>
/// <param name="cmdType">语句类型</param>
/// <param name="cmdText">SQL语句</param>
/// <returns>记录集</returns>
public DbDataReader ExecuteReader(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
{
this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
reader = this.command.ExecuteReader();
this.command.Parameters.Clear();
return reader;
}
/// <summary>
/// 执行SQL语句
/// </summary>
/// <param name="cmdType">语句类型</param>
/// <param name="cmdText">SQL语句</param>
/// <returns>返回数据表</returns>
public DataTable ExecuteTable(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
{
DataTable dt = new DataTable();
this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
this.dataAdapter.SelectCommand = this.command;
this.dataAdapter.Fill(dt);
this.command.Parameters.Clear();
return dt;
} /// <summary>
/// 返回执行SQL语句第一个值
/// </summary>
/// <param name="cmdType">语句类型</param>
/// <param name="cmdText">SQL语句</param>
/// <returns>执行结果</returns>
public object ExecuteScalar(CommandType cmdType, string cmdText, ParameterCollection dbParameter)
{
object val = null;
this.PrepareCommand(this.command, this.connection, this.transaction, cmdType, cmdText, dbParameter);
val = this.command.ExecuteScalar();
this.command.Parameters.Clear();
return val;
} private void PrepareCommand(DbCommand cmd, DbConnection conn, DbTransaction trans, CommandType cmdType, string cmdText, ParameterCollection cmdParms)
{
this.command.Parameters.Clear(); if (conn.State != ConnectionState.Open)
{
conn.Open();
}
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (trans != null)
{
cmd.Transaction = trans;
}
cmd.CommandType = cmdType;
if (cmdParms != null)
{
foreach (DbParameter parm in cmdParms)
{
cmd.Parameters.Add(parm);
}
}
} #region 数据库事务处理
/// <summary>
/// 开启事务
/// </summary>
public void BeginTransaction()
{
if (this.connection.State != ConnectionState.Open)
{
this.connection.Open();
}
transaction = this.connection.BeginTransaction();
}
/// <summary>
/// 提交事务
/// </summary>
public void Commit()
{
if (this.transaction != null)
{
this.transaction.Commit();
}
}
/// <summary>
/// 回滚事务
/// </summary>
public void Rollback()
{
if (this.transaction != null)
{
this.transaction.Rollback();
}
}
#endregion #region 创建数据库参数
/// <summary>
/// 创建参数
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">类型</param>
/// <param name="value">值</param>
/// <param name="Size">大小</param>
/// <param name="direction">Input|OutPut</param>
public DbParameter CreateParameter(string parameterName, DbType dbType, object value, int size, ParameterDirection direction)
{
DbParameter ps = this.CreateParameter(parameterName, dbType, value, direction);
ps.Size = size;
return ps;
} /// <summary>
/// 创建参数
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">类型</param>
/// <param name="value">值</param>
/// <param name="Size">大小</param>
public DbParameter CreateParameter(string parameterName, DbType dbType, object value, int size)
{
DbParameter ps = this.CreateParameter(parameterName, dbType, value);
ps.Size = size;
return ps;
} /// <summary>
/// 创建参数
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">类型</param>
/// <param name="value">值</param>
public abstract DbParameter CreateParameter(string parameterName, DbType dbType, object value); /// <summary>
/// 创建参数
/// </summary>
/// <param name="parameterName">参数名称</param>
/// <param name="dbType">类型</param>
/// <param name="value">值</param>
/// <param name="direction">Input|OutPut</param>
public DbParameter CreateParameter(string parameterName, DbType dbType, object value, ParameterDirection direction)
{
DbParameter ps = this.CreateParameter(parameterName, dbType, value);
ps.Direction = direction;
return ps;
}
#endregion private bool alreadyDisposed = false; /// <summary>
/// 回收资源
/// </summary>
public void Dispose()
{
//调用带参数的Dispose方法, 释放托管和非托管资源
Dispose(true);
//手动调用了Dispose释放资源,那么析构函数就是不必要的了, 这里阻止GC调用析构函数
GC.SuppressFinalize(this);
} /// <summary>
/// protected的Dispose方法, 保证不会被外部调用,传入bool值disposing以确定是否释放托管资源
/// </summary>
protected void Dispose(bool disposing)
{
//保证不重复释放
if (alreadyDisposed)
return;
if (disposing)
{
//销毁事务
if (transaction != null)
{
transaction.Dispose();
transaction = null;
}
//关闭游标
if (reader != null && reader.IsClosed == false)
{
reader.Close();
reader.Dispose();
reader = null;
}
//关闭连接
if (connection != null && connection.State == ConnectionState.Open)
{
connection.Close();
connection.Dispose();
connection = null;
}
}
alreadyDisposed = true;
}
}
}
分页语法:OFFSET FETCH NEXT
要是像楼主都说的这个样的话,看你的分页是存储过程还是后台拼的SQL语句,这个还要看具体的分页代码~都有关系。
2.datareader对于数据量大的时候,一直保持数据库的连接状态。建议返回datatable或者dataset,这样即使查询时间久,也不会占有一个数据库连接!就asp.net而言数据库连接很宝贵啊,尽量少的减少打开连接次数,尽量减少打开时间!
3.如果一定要用datareader,个人觉得,增加数据库连接池的数量,对于datareader操作,做个对象池试试!
再针对常用查询条件加索引优化
几十万的数据应该没有什么问题
感觉只能从用户侧 或者 改用存储分页之类的来处理比较好
跟所谓的并发没有关系。我怀疑你根本不知道如何多人并发测试,你的代码在多人并发是必然出错,可是你竟然说没有出错。而你只是在说在一次查询很慢时(同一个人因为等不及其结果而立刻发起了另一个查询)此时才出错。可见你只是自己做了调试,根本没有任何多用户使用的经验,也没有经过这类测试。如果做过真正的测试,其实问题一眼就能看出来。修改过的代码就是这样的:
var cmd= CreateNewCommand(sql);
cmd.Connection = CreateNewSqlConnection();
using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;
}
必须创建新的SqlCommand对象,新的(独立的)SqlConnection对象,而不能共享。asp.net处理客户端请求是多线程并发的,因此那种以为“省得创建对象了”的代码,当然就会出现共享冲突。
在统一个链接上打开企图打开多个DataReader
using (DbDataReader rd = cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (cmd.Connection.State == ConnectionState.Closed)
cmd.Connection = conn;
rd = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rd);
rd.Close();
return dt;
恕我愚钝,初学ASP.NET没多久,想请教各位大能:
1 从楼主的程序上看不出connection是从什么地方传过来的,应该是前面代码创建的吧(是不是前面就是创建Connection和创建command的代码,楼主省事没贴,似乎Connection没法在asp.net的页面处理线程之间共享吧)
2不管是否查询处理完,即使再点同样链接或其他链接,应该在服务器端是另外一个线程处理了吧,似乎不会导致并发冲突,最多连接池被占满,系统响应迟钝。
3 我个人感觉是不是楼主的using只包含了第一行有问题呢?如果去掉using怎么样?