C# 如何使用SqlCommand返回多个结果集?
我是否可以执行多个查询并仅执行一次C# 如何使用SqlCommand返回多个结果集?,c#,sql-server,ado.net,C#,Sql Server,Ado.net,我是否可以执行多个查询并仅执行一次SqlCommand返回它们的结果?创建一个具有多个选择的存储过程,并填充数据集 using (SqlConnection conn = new SqlConnection(connection)) { DataSet dataset = new DataSet(); SqlDataAdapter adapter = new SqlDataAdapter(); adapter.SelectCommand = new SqlCommand(
SqlCommand
返回它们的结果?创建一个具有多个选择的存储过程,并填充数据集
using (SqlConnection conn = new SqlConnection(connection))
{
DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("MyProcedure", conn);
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.Fill(dataset);
return dataset;
}
对于存储过程中的每个select,返回的数据集的Tables数组中将有一个DataTable
。请参阅(调用返回SqlDataReader):
读取批处理Transact-SQL语句的结果时,将数据读取器前进到下一个结果[set]
例如:
string commandText = @"SELECT Id, ContactId
FROM dbo.Subscriptions;
SELECT Id, [Name]
FROM dbo.Contacts;";
List<Subscription> subscriptions = new List<Subscription>();
List<Contact> contacts = new List<Contact>();
using (SqlConnection dbConnection = new SqlConnection(@"Data Source=server;Database=database;Integrated Security=true;"))
{
dbConnection.Open();
using (SqlCommand dbCommand = dbConnection.CreateCommand())
{
dbCommand.CommandText = commandText;
using(SqlDataReader reader = dbCommand.ExecuteReader())
{
while(reader.Read())
{
subscriptions.Add(new Subscription()
{
Id = (int)reader["Id"],
ContactId = (int)reader["ContactId"]
});
}
// this advances to the next resultset
reader.NextResult();
while(reader.Read())
{
contacts.Add(new Contact()
{
Id = (int)reader["Id"],
Name = (string)reader["Name"]
});
}
}
}
}
string commandText=@“选择Id,联系人Id
来自dbo.Subscriptions;
选择Id、[名称]
来自dbo.Contacts;“;
列表订阅=新列表();
列表联系人=新列表();
使用(SqlConnection-dbConnection=newsqlconnection(@“数据源=服务器;数据库=数据库;集成安全性=true;”)
{
dbConnection.Open();
使用(SqlCommand dbCommand=dbConnection.CreateCommand())
{
dbCommand.CommandText=CommandText;
使用(SqlDataReader=dbCommand.ExecuteReader())
{
while(reader.Read())
{
subscriptions.Add(新订阅()
{
Id=(int)读卡器[“Id”],
ContactId=(int)读卡器[“ContactId”]
});
}
//这将前进到下一个结果集
reader.NextResult();
while(reader.Read())
{
联系人。添加(新联系人()
{
Id=(int)读卡器[“Id”],
名称=(字符串)读取器[“名称”]
});
}
}
}
}
其他例子:
像“dapper”这样的工具使这变得非常容易,无论您使用的是特别的文本查询还是存储过程;例如:
using(var multi = conn.QueryMultiple(sql, args))
{
var customers = multi.Read<Customer>().AsList(); // first grid
var regionName = multi.ReadFirstOrDefault<string>(); // second grid
var addresses = multi.Read<Address>().AsList(); // third grid
// todo: use those things
}
使用(var multi=conn.QueryMultiple(sql,args))
{
var customers=multi.Read().AsList();//第一个网格
var regionName=multi.ReadFirstOrDefault();//第二个网格
var addresses=multi.Read().AsList();//第三个网格
//托多:用那些东西
}
也可以通过read[]
的可选参数读取单个网格,而无需缓冲(作为读卡器本身上的一个打开的IEnumerable
),这就是我用于返回多个结果集的方法
public abstract class BaseRepo
{
private string _connectionString;
protected BaseRepo(string connectionString)
{
_connectionString = connectionString;
}
private SqlConnection GetSqlConnection(int commandTimeout, CommandType commandType, ref SqlCommand sqlCmd)
{
var connection = new SqlConnection(_connectionString);
connection.Open();
sqlCmd.Connection = connection;
sqlCmd.CommandTimeout = commandTimeout;
sqlCmd.CommandType = commandType;
return connection;
}
protected int ExecuteSql(SqlCommand sqlCmd, int commandTimeout = 30, CommandType commandType = CommandType.Text)
{
using (var connection = GetSqlConnection(commandTimeout, commandType, ref sqlCmd))
{
return sqlCmd.ExecuteNonQuery();
}
}
protected IEnumerable<T> ExecuteSqlReader<T>(Func<IDataRecord, T> CreateObject, SqlCommand sqlCmd, int commandTimeout = 30, CommandType commandType = CommandType.Text)
{
using (var connection = GetSqlConnection(commandTimeout, commandType, ref sqlCmd))
{
using (var reader = sqlCmd.ExecuteReader())
return ExecuteReader(CreateObject, reader);
}
}
protected Tuple<IEnumerable<T1>, IEnumerable<T2>> ExecuteSqlReader<T1,T2>(Func<IDataRecord, T1> CreateObject1, Func<IDataRecord, T2> CreateObject2, SqlCommand sqlCmd, int commandTimeout = 30, CommandType commandType = CommandType.Text)
{
using (var connection = GetSqlConnection(commandTimeout, commandType, ref sqlCmd))
{
using (var reader = sqlCmd.ExecuteReader())
{
var result1 = ExecuteReader(CreateObject1, reader).ToList();
var result2 = ExecuteReader(CreateObject2, reader).ToList();
return Tuple.Create<IEnumerable<T1>, IEnumerable<T2>>(result1, result2);
}
}
}
protected Tuple<IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>> ExecuteSqlReader<T1, T2, T3>(Func<IDataRecord, T1> CreateObject1, Func<IDataRecord, T2> CreateObject2, Func<IDataRecord, T3> CreateObject3, SqlCommand sqlCmd, int commandTimeout = 30, CommandType commandType = CommandType.Text)
{
using (var connection = GetSqlConnection(commandTimeout, commandType, ref sqlCmd))
{
using (var reader = sqlCmd.ExecuteReader())
{
var result1 = ExecuteReader(CreateObject1, reader).ToList();
var result2 = ExecuteReader(CreateObject2, reader).ToList();
var result3 = ExecuteReader(CreateObject3, reader).ToList();
return Tuple.Create<IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>>(result1, result2, result3);
}
}
}
protected Tuple<IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>, IEnumerable<T4>> ExecuteSqlReader<T1, T2, T3, T4>(Func<IDataRecord, T1> CreateObject1, Func<IDataRecord, T2> CreateObject2, Func<IDataRecord, T3> CreateObject3, Func<IDataRecord, T4> CreateObject4, SqlCommand sqlCmd, int commandTimeout = 30, CommandType commandType = CommandType.Text)
{
using (var connection = GetSqlConnection(commandTimeout, commandType, ref sqlCmd))
{
using (var reader = sqlCmd.ExecuteReader())
{
var result1 = ExecuteReader(CreateObject1, reader).ToList();
var result2 = ExecuteReader(CreateObject2, reader).ToList();
var result3 = ExecuteReader(CreateObject3, reader).ToList();
var result4 = ExecuteReader(CreateObject4, reader).ToList();
return Tuple.Create<IEnumerable<T1>, IEnumerable<T2>, IEnumerable<T3>, IEnumerable<T4>>(result1, result2, result3, result4);
}
}
}
private IEnumerable<T> ExecuteReader<T>(Func<IDataRecord, T> CreateObject, SqlDataReader reader)
{
while (reader.Read())
{
yield return CreateObject(reader);
}
reader.NextResult();
}
}
公共抽象类BaseRepo
{
私有字符串_connectionString;
受保护的BaseRepo(字符串连接字符串)
{
_connectionString=connectionString;
}
私有SqlConnection GetSqlConnection(int commandTimeout、CommandType CommandType、ref SqlCommand sqlCmd)
{
var connection=newsqlconnection(_connectionString);
connection.Open();
sqlCmd.Connection=Connection;
sqlCmd.CommandTimeout=CommandTimeout;
sqlCmd.CommandType=CommandType;
回路连接;
}
受保护的int ExecuteSql(SqlCommand sqlCmd,int commandTimeout=30,CommandType CommandType=CommandType.Text)
{
使用(var connection=GetSqlConnection(commandTimeout,commandType,ref-sqlCmd))
{
返回sqlCmd.ExecuteNonQuery();
}
}
受保护的IEnumerable ExecuteSqlReader(Func CreateObject,SqlCommand sqlCmd,int commandTimeout=30,CommandType CommandType=CommandType.Text)
{
使用(var connection=GetSqlConnection(commandTimeout,commandType,ref-sqlCmd))
{
使用(var reader=sqlCmd.ExecuteReader())
返回ExecuteReader(CreateObject,reader);
}
}
受保护的元组ExecuteSqlReader(Func CreateObject1、Func CreateObject2、SqlCommand sqlCmd、int commandTimeout=30、CommandType CommandType=CommandType.Text)
{
使用(var connection=GetSqlConnection(commandTimeout,commandType,ref-sqlCmd))
{
使用(var reader=sqlCmd.ExecuteReader())
{
var result1=ExecuteReader(CreateObject1,reader).ToList();
var result2=ExecuteReader(CreateObject2,reader).ToList();
返回Tuple.Create(result1,result2);
}
}
}
受保护的元组ExecuteSqlReader(Func CreateObject1、Func CreateObject2、Func CreateObject3、SqlCommand sqlCmd、int commandTimeout=30、CommandType CommandType=CommandType.Text)
{
使用(var connection=GetSqlConnection(commandTimeout,commandType,ref-sqlCmd))
{
使用(var reader=sqlCmd.ExecuteReader())
{
var result1=ExecuteReader(CreateObject1,reader).ToList();
var result2=ExecuteReader(CreateObject2,reader).ToList();
var result3=ExecuteReader(CreateObject3,reader).ToList();
返回Tuple.Create(result1、result2、result3);
}
}
}
受保护的元组ExecuteSqlReader(Func CreateObject1、Func CreateObject2、Func CreateObject3、Func CreateObject4、SqlCommand sqlCmd、int commandTimeout=30、CommandType CommandType=CommandType.Text)
{
使用(var connection=GetSqlConnection(commandTimeout,commandType,ref-sqlCmd))
{
使用(var reader=sqlCmd.ExecuteReader())
{
var result1=ExecuteReader(CreateObject1,reader).ToList();
var result2=ExecuteReader(CreateObject2,reader).ToList();
var result3=ExecuteReader(CreateObject3,reader).ToList();
var result4=ExecuteReader(CreateObject4,reader).ToList();
返回Tuple.Create(result1、result2、result3、result4);
}
}
}
私有IEnumerable ExecuteReader(Func CreateObject、SqlDataReader)
{
while(reader.Read())
{
返回CreateObject(读卡器);
}
reader.NextResult();
}
}
然后我就这样继承了它:
public class ReviewRepo : BaseRepo
{
public ReviewRepo(string connectionString) : base(connectionString) { }
public ReviewPageableResult GetAllReviews(string productType, string serviceType, int pageNumber, int itemsPerPage, string sortBy, string sortDirection)
{
var parameters = new List<SqlParameter>
{
new SqlParameter("ProductRefDescription", productType),
new SqlParameter("ServiceRefDescription", serviceType),
new SqlParameter("ZipCodes", "NULL"),
new SqlParameter("PageNumber", pageNumber),
new SqlParameter("ItemsPerPage", itemsPerPage),
new SqlParameter("SortBy", sortBy),
new SqlParameter("SortDirection", sortDirection)
};
var cmd = new SqlCommand("dbo.GetReviews");
cmd.Parameters.AddRange(parameters.ToArray());
var results = ExecuteSqlReader(CreateReview, CreateReviewPageableResult, cmd, commandType: CommandType.StoredProcedure);
var reviewResult = results.Item2.Single();
reviewResult.Items = results.Item1;
return reviewResult;
}
public ReviewPageableResult GetReviewsByZip(string productType, string serviceType, string zipCodes, int pageNumber, int itemsPerPage, string sortBy, string sortDirection)
{
var parameters = new List<SqlParameter>
{
new SqlParameter("ProductRefDescription", productType),
new SqlParameter("ServiceRefDescription", serviceType),
new SqlParameter("ZipCodes", zipCodes),
new SqlParameter("PageNumber", pageNumber),
new SqlParameter("ItemsPerPage", itemsPerPage),
new SqlParameter("SortBy", sortBy),
new SqlParameter("SortDirection", sortDirection)
};
var cmd = new SqlCommand("dbo.GetReviewsByZipCodes");
cmd.Parameters.AddRange(parameters.ToArray());
var results = ExecuteSqlReader(CreateReview, CreateReviewPageableResult, cmd, commandType: CommandType.StoredProcedure);
var reviewResult = results.Item2.Single();
reviewResult.Items = results.Item1;
return reviewResult;
}
private Review CreateReview(IDataRecord record)
{
return new Review
{
PageReviewId = (int)record["PageReviewId"],
ProductRefId = (Guid)record["ProductRefId"],
ServiceTypeRefId = Convert.IsDBNull(record["ServiceTypeRefId"]) ? Guid.Empty : (Guid)record["ServiceTypeRefId"],
TerritoryId = Convert.IsDBNull(record["TerritoryId"]) ? Guid.Empty : (Guid)record["TerritoryId"],
FirstName = $"{record["FirstName"]}",
LastName = $"{record["LastName"]}",
City = $"{record["City"]}",
State = $"{record["State"]}",
Answer = $"{record["Answer"]}",
Rating =(double)record["Rating"],
SurveyDate = (DateTime)record["SurveyDate"]
};
}
private ReviewPageableResult CreateReviewPageableResult(IDataRecord record)
{
return new ReviewPageableResult
{
AverageRating = (double)record["AverageRating"],
Count1Stars = (int)record["Count1Stars"],
Count2Stars = (int)record["Count2Stars"],
Count3Stars = (int)record["Count3Stars"],
Count4Stars = (int)record["Count4Stars"],
Count5Stars = (int)record["Count5Stars"],
ItemsPerPage = (int)record["ItemsPerPage"],
PageNumber = (int)record["PageNumber"],
TotalCount = (int)record["TotalCount"],
};
}
}
public class ReviewRepo:BaseRe
List<List<Dictionary<string, object>>>
List<Dictionary<string, object>>
private static List<List<Dictionary<string, object>>> ProcessReader(SqlCommand command)
{
var tables = new List<List<Dictionary<string, object>>>();
using (var reader = command.ExecuteReader())
{
do
{
var table = new List<Dictionary<string, object>>();
while (reader.Read())
table.Add(Read(reader));
tables.Add(table);
} while (reader.NextResult());
}
return tables;
}
private static Dictionary<string, object> Read(IDataRecord reader)
{
var row = new Dictionary<string, object>();
for (var i = 0; i < reader.FieldCount; i++)
{
var val = reader[i];
row[reader.GetName(i)] = val == DBNull.Value ? null : val;
}
return row;
}
Dim dt1, dt2, dt3As New DataTable
Dim command As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim Sql1, Sql2, Sql3 As String
Sql1 = "select id, CurName from Table1 where IS_Deleted=0 order by id"
Sql2 = "select id ,Item from Table2 order by id"
Sql3 = "select id ,SellPrice from Table3 order by id"
Try
conn1.Open()
command = New SqlCommand(Sql1, conn1)
command.CommandType = CommandType.Text
adapter.SelectCommand = command
adapter.Fill(ds, "dt1")
adapter.SelectCommand.CommandText = Sql2
adapter.Fill(ds, "dt2")
adapter.SelectCommand.CommandText = Sql3
adapter.Fill(ds, "dt3")
adapter.Dispose()
command.Dispose()
conn1.Close()
cmbCurrency.DataSource = ds.Tables("dt1")
cmbCurrency.DisplayMember = "CurName"
cmbCurrency.ValueMember = "id"
cmbCurrency.SelectedIndex = -1
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''|
cmbGroups.DataSource = ds.Tables("dt2")
cmbGroups.DisplayMember = "Item"
cmbGroups.ValueMember = "id"
cmbGroups.SelectedIndex = -1
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''|
cmbUnits.DataSource = ds.Tables("dt3")
cmbUnits.DisplayMember = "SellPrice"
cmbUnits.ValueMember = "id"
cmbUnits.SelectedIndex = -1
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''|
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
public List<List<Dictionary<string, object>>> ExecuteSqlReader(string cmd, int commandTimeout = 30, CommandType commandType = CommandType.Text)
{
var sqlCmd = new SqlCommand(cmd);
var allRecord = new List<List<Dictionary<string, object>>>();
using (var connection = GetSqlConnection(commandTimeout, commandType, ref sqlCmd))
{
using (var reader = sqlCmd.ExecuteReader())
{
if (reader.HasRows)
{
var result = new List<Dictionary<string, object>>();
while (reader.Read())
{
result = GetTableRowData(reader);
}
allRecord.Add(result);
}
while (reader.NextResult())
{
if (reader.HasRows)
{
var result = new List<Dictionary<string, object>>();
while (reader.Read())
{
result = GetTableRowData(reader);
}
allRecord.Add(result);
}
}
}
}
return allRecord;
}