C# SQL Server:具有多个结果集的存储过程存在问题
我试图从EF5中的存储过程中获取多个结果集。我正试图减少我们平台中最昂贵功能的数据库往返次数 我们有一个通过服务器发送事件进行更新的视图。当视图数据更改时,每个用户都需要接收带有更新数据的自定义视图。我们当前的方法是获取所有连接的用户,然后从数据库中获取每个用户的视图。因为这非常昂贵,所以我们试图通过实现对存储过程的一个调用来降低成本,该调用返回多个结果 我有以下代码:C# SQL Server:具有多个结果集的存储过程存在问题,c#,sql,sql-server,entity-framework,tsql,C#,Sql,Sql Server,Entity Framework,Tsql,我试图从EF5中的存储过程中获取多个结果集。我正试图减少我们平台中最昂贵功能的数据库往返次数 我们有一个通过服务器发送事件进行更新的视图。当视图数据更改时,每个用户都需要接收带有更新数据的自定义视图。我们当前的方法是获取所有连接的用户,然后从数据库中获取每个用户的视图。因为这非常昂贵,所以我们试图通过实现对存储过程的一个调用来降低成本,该调用返回多个结果 我有以下代码: var sql = "DECLARE @users UserList INSERT INTO @users(row) VALU
var sql = "DECLARE @users UserList INSERT INTO @users(row) VALUES {0}" +
"EXEC dbo.GetTracklistViews(@users, '{1}');";
var sql_shard = "('{0}'),";
var sql_shard_last = "('{0}')";
var users = new List<Guid>();
//Logic to get all connected users
var builder = new StringBuilder();
for (var i = 0; i < users.Count; i++)
if (i < (users.Count - 1))
builder.Append(string.Format(sql_shard, users[i]));
else
builder.Append(string.Format(sql_shard_last, users[i]));
using (var ctx = new spottyData())
{
ctx.Database.Initialize(force: false);
ctx.Database.Connection.Open();
using (var cmd = ctx.Database.Connection.CreateCommand())
{
cmd.CommandText = string.Format(sql, builder.ToString(), juke.ToString());
var result = cmd.ExecuteReader();
while (result.NextResult())
{
var set = ((IObjectContextAdapter)ctx)
.ObjectContext
.Translate<tracklist>(result, "tracklist", System.Data.Objects.MergeOption.NoTracking)
.ToArray();
//Send event with 'set' data
}
}
}
首先-您不应该使用字符串中以逗号分隔的值列表作为参数。SQL server解析和拆分它的效率非常低。相反,存储过程应该使用表值参数 第二,尽量避免出现多个结果集。很乱。 因为所有的结果集都是相同类型的表,所以我只需要创建一个新类,例如称之为UserTrackList,它的属性与Tracklist相同,UserId多加1。它甚至可以从TrackList继承 例如: 要传入的表值类型: 创建类型指南列表 作为桌子 [id]UNIQUEIDENTIFIER-<假设这就是您实际传递的内容? ; 存储过程定义 创建过程dbo.getTrackListView @用户指南列表只读, @juke NVARCHAR1000-<我不知道这个参数是什么! 像 开始 -选择一堆连接到此表值参数上的内容? 终止 如何在C中调用过程
var sql = "EXEC dbo.GetTrackListViews @users, @juke";
var prms = new List<System.Data.SqlClient.SqlParameter>();
//build table valued parameter
var tbl = new DataTable();
tbl.Columns.Add(new DataColumn("id", typeof(guid));
foreach(var user in users) //assume these are guids.
{ tbl.Rows.Add(user) }
var prm1 = new System.Data.SqlClient.SqlParameter("users", SqlDbType.Structured);
prm1.Value = tbl;
prm1.TypeName = "GuidList";
prms.Add(prm1);
// other parameter is easy:
var prm2 = new System.Data.SqlClient.SqlParameter("juke", juke.ToString());
prms.Add(prm2);
List<UserTrackList> results;
using (var ctx = new spottyData())
{
var query = ctx.Database.SqlQuery<UserTrackList>(sql, prms.ToArray());
results = query.ToList();
// NB - this works if the property names/types in the type "tracklist"
// match the column names/types in the returned resultset.
}
// example processing the results
foreach (var tracklist in results.GroupBy(x => x.UserId)
{
user = users.First(x => x == tracklist.Key);
//do something with the grouped result
}
可能将GetTrackListView的代码放在此处。请使用SQL Server探查器查找实际执行的内容。抱歉,在您粘贴的代码中,我找不到EXEC dbo.GetTrackListView。我只能看到EXEC dbo.GetFriends。你能帮我解决这个问题吗?谢谢,已经解决了,但还是有同样的问题。非常感谢!这太棒了!
var sql = "EXEC dbo.GetTrackListViews @users, @juke";
var prms = new List<System.Data.SqlClient.SqlParameter>();
//build table valued parameter
var tbl = new DataTable();
tbl.Columns.Add(new DataColumn("id", typeof(guid));
foreach(var user in users) //assume these are guids.
{ tbl.Rows.Add(user) }
var prm1 = new System.Data.SqlClient.SqlParameter("users", SqlDbType.Structured);
prm1.Value = tbl;
prm1.TypeName = "GuidList";
prms.Add(prm1);
// other parameter is easy:
var prm2 = new System.Data.SqlClient.SqlParameter("juke", juke.ToString());
prms.Add(prm2);
List<UserTrackList> results;
using (var ctx = new spottyData())
{
var query = ctx.Database.SqlQuery<UserTrackList>(sql, prms.ToArray());
results = query.ToList();
// NB - this works if the property names/types in the type "tracklist"
// match the column names/types in the returned resultset.
}
// example processing the results
foreach (var tracklist in results.GroupBy(x => x.UserId)
{
user = users.First(x => x == tracklist.Key);
//do something with the grouped result
}