C# SQL Server:具有多个结果集的存储过程存在问题

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

我试图从EF5中的存储过程中获取多个结果集。我正试图减少我们平台中最昂贵功能的数据库往返次数

我们有一个通过服务器发送事件进行更新的视图。当视图数据更改时,每个用户都需要接收带有更新数据的自定义视图。我们当前的方法是获取所有连接的用户,然后从数据库中获取每个用户的视图。因为这非常昂贵,所以我们试图通过实现对存储过程的一个调用来降低成本,该调用返回多个结果

我有以下代码:

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
}