C# QueryMultiple结果集顺序已更改

C# QueryMultiple结果集顺序已更改,c#,dapper,C#,Dapper,我正在执行一个存储过程,使用QueryMultiple返回多组数据 var gridReader = db.QueryMultiple("sp", parameters, commandType: CommandType.StoredProcedure); 我可以很容易地得到每一套,因为我知道他们会回来的顺序 SELECT * FROM dbo.Set1;

我正在执行一个存储过程,使用
QueryMultiple
返回多组数据

var gridReader = db.QueryMultiple("sp", 
                                  parameters, 
                                  commandType: CommandType.StoredProcedure);
我可以很容易地得到每一套,因为我知道他们会回来的顺序

SELECT * FROM dbo.Set1;
SELECT * FROM dbo.Set2;
SELECT * FROM dbo.Set3;
我该怎么办

我最初的尝试是迭代每个网格,检查列名。这在一开始似乎很有效,但除了手动设置每个字段外,我无法弄清楚如何将网格投影到类中。我使用Dapper的主要原因是它能帮我做到这一点

while (true)
{
    var grid = gridReader.Read();
    IDictionary<string, object> row = grid.FirstOrDefault();

    if (row == null)
        break;

    if (row.Keys.Contains("Set1_UniqueColumnName"))
    {
        // Need something like grid.Read<Set1>();
    }
    else if (row.Keys.Contains("Set2_UniqueColumnName")) { }
    else if (row.Keys.Contains("Set3_UniqueColumnName")) { }
}
while(true)
{
var grid=gridReader.Read();
IDictionary行=grid.FirstOrDefault();
if(行==null)
打破
if(row.Keys.Contains(“Set1_UniqueColumnName”))
{
//需要类似于grid.Read()的东西;
}
else if(row.Keys.Contains(“Set2_UniqueColumnName”){}
else if(row.Keys.Contains(“Set3_UniqueColumnName”){}
}

我的第二个想法是将每个网格读入一个类中,检查该类的唯一字段是否为空/默认值,如果测试失败,则尝试下一个类。但这显然行不通
.Read()
将返回下一个结果网格。此解决方案要求我能够反复读取同一个网格。

Dapper提供了一个
IDataReader.GetRowParser
扩展方法,该方法支持每行类型切换。从整洁的文件

通常,您希望将给定表中的所有行视为相同的行 数据类型。但是,在某些情况下,使用 能够将不同的行解析为不同的数据类型。这就是 IDataReader.GetRowParser很方便

假设您有一个名为“Shapes”的数据库表,其列为:Id, 输入、和数据,然后要将其行解析为圆形、方形或三角形 基于类型列的值的三角形对象

给我指出了正确的方向。需要结合使用ADO.NET和Dapper。基本上使用ADO.NET检索和迭代数据,但使用Dapper将行解析为我的对象。请注意,如果结果集实际返回0行,则在while循环中使用
FieldCount
。我们希望它继续下一个结果集,而不是跳出循环

Set1 set1 = null;
var set2 = new List<Set2>();
Set3 set3 = null;

using (var command = new SqlCommand("sp", conn))
{
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddRange(parameters);
    command.Connection.Open();

    using (var reader = command.ExecuteReader())
    {
        while (reader.FieldCount > 0)
        {
            var set1Parser = reader.GetRowParser<Set1>();
            var set2Parser = reader.GetRowParser<Set2>();
            var set3Parser = reader.GetRowParser<Set3>();

            var isSet1 = HasColumn(reader, "Set1_UniqueColumnName");
            var isSet2 = HasColumn(reader, "Set2_UniqueColumnName");
            var isSet3 = HasColumn(reader, "Set3_UniqueColumnName");

            while (reader.Read())
            {
                if (isSet1)
                {
                    set1 = set1Parser(reader);
                }
                else if (isSet2)
                {
                    set2.Add(set2Parser(reader));
                }
                else if (isSet3)
                {
                    set3 = set3Parser(reader);
                }
            }

            reader.NextResult();
        }
    }
}
Set1 Set1=null;
var set2=新列表();
Set3 Set3=null;
使用(var命令=新的SqlCommand(“sp”,conn))
{
command.CommandType=CommandType.storedProcess;
command.Parameters.AddRange(参数);
command.Connection.Open();
使用(var reader=command.ExecuteReader())
{
而(reader.FieldCount>0)
{
var set1Parser=reader.GetRowParser();
var set2Parser=reader.GetRowParser();
var set3Parser=reader.GetRowParser();
var isSet1=HasColumn(读取器,“Set1_UniqueColumnName”);
var isSet2=HasColumn(读取器,“Set2_UniqueColumnName”);
var isSet3=HasColumn(读取器,“Set3_UniqueColumnName”);
while(reader.Read())
{
如果(isSet1)
{
set1=set1Parser(读卡器);
}
否则如果(isSet2)
{
set2.Add(set2Parser(reader));
}
否则如果(isSet3)
{
set3=set3Parser(读卡器);
}
}
reader.NextResult();
}
}
}
publicstaticboolhaspolumn(IDataReader读取器,字符串columnName)
{
对于(变量i=0;i
感谢您为我指明了正确的方向!我想我需要
GetRowParser
,但我不太明白。将其与SqlDataReader相结合就成功了。
while (true)
{
    var grid = gridReader.Read();
    IDictionary<string, object> row = grid.FirstOrDefault();

    if (row == null)
        break;

    if (row.Keys.Contains("Set1_UniqueColumnName"))
    {
        // Need something like grid.Read<Set1>();
    }
    else if (row.Keys.Contains("Set2_UniqueColumnName")) { }
    else if (row.Keys.Contains("Set3_UniqueColumnName")) { }
}
var shapes = new List<IShape>();
using (var reader = connection.ExecuteReader("select * from Shapes"))
{
    // Generate a row parser for each type you expect.
    // The generic type <IShape> is what the parser will return.
    // The argument (typeof(*)) is the concrete type to parse.
    var circleParser = reader.GetRowParser<IShape>(typeof(Circle));
    var squareParser = reader.GetRowParser<IShape>(typeof(Square));
    var triangleParser = reader.GetRowParser<IShape>(typeof(Triangle));

    var typeColumnIndex = reader.GetOrdinal("Type");

    while (reader.Read())
    {
        IShape shape;
        var type = (ShapeType)reader.GetInt32(typeColumnIndex);
        switch (type)
        {
            case ShapeType.Circle:
                shape = circleParser(reader);
                break;
            case ShapeType.Square:
                shape = squareParser(reader);
                break;
            case ShapeType.Triangle:
                shape = triangleParser(reader);
                break;
            default:
                throw new NotImplementedException();
        }

        shapes.Add(shape);
    }
}
using (command = new SqlCommand("sp", connection))
{
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddRange(parameters);

    using (var reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            // read row columns
        }
    }
}
Set1 set1 = null;
var set2 = new List<Set2>();
Set3 set3 = null;

using (var command = new SqlCommand("sp", conn))
{
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddRange(parameters);
    command.Connection.Open();

    using (var reader = command.ExecuteReader())
    {
        while (reader.FieldCount > 0)
        {
            var set1Parser = reader.GetRowParser<Set1>();
            var set2Parser = reader.GetRowParser<Set2>();
            var set3Parser = reader.GetRowParser<Set3>();

            var isSet1 = HasColumn(reader, "Set1_UniqueColumnName");
            var isSet2 = HasColumn(reader, "Set2_UniqueColumnName");
            var isSet3 = HasColumn(reader, "Set3_UniqueColumnName");

            while (reader.Read())
            {
                if (isSet1)
                {
                    set1 = set1Parser(reader);
                }
                else if (isSet2)
                {
                    set2.Add(set2Parser(reader));
                }
                else if (isSet3)
                {
                    set3 = set3Parser(reader);
                }
            }

            reader.NextResult();
        }
    }
}
public static bool HasColumn(IDataReader reader, string columnName)
{
    for (var i = 0; i < reader.FieldCount; i++)
    {
        if (reader.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
        {
            return true;
        }
    }

    return false;
}