C# 在使用Entity Framework执行多个原始查询后,如何读取多个数据集?

C# 在使用Entity Framework执行多个原始查询后,如何读取多个数据集?,c#,sql-server,entity-framework,C#,Sql Server,Entity Framework,我有多个依赖于多个临时表的查询,一旦执行完成,我需要返回多个数据集并映射到C对象 这里有一个例子 我的实际查询更加复杂和冗长,这就是为什么我需要使用temp 为了提高性能,为了简单起见,我减少了表格 如您所见,我正在执行多个查询,然后最终结果是需要映射到我的C模型的两个数据集 我试着执行上面的查询,这些查询按节分隔成多个实体框架命令,如下所示 context.Database.ExecuteSqlCommand("Queries from section 1 above"); var recor

我有多个依赖于多个临时表的查询,一旦执行完成,我需要返回多个数据集并映射到C对象

这里有一个例子

我的实际查询更加复杂和冗长,这就是为什么我需要使用temp 为了提高性能,为了简单起见,我减少了表格

如您所见,我正在执行多个查询,然后最终结果是需要映射到我的C模型的两个数据集

我试着执行上面的查询,这些查询按节分隔成多个实体框架命令,如下所示

context.Database.ExecuteSqlCommand("Queries from section 1 above");
var records = context.Database.SqlQuery<OtherRecord>("Queries from section 2 above").ToList();
var otherRecords = context.Database.SqlQuery<YetOtherRecord>("Queries from section 3 above").ToList();
但是,这不起作用,因为每个命令都会向数据库发出一个新的连接,因此临时表只能用于第一个查询,即上文第1节中的context.database.ExecuteSqlCommandQueries

如何运行上面的所有查询并生成两个数据集,而不必在每次调用时创建临时表?

学习

您需要创建一个DbDataReader并从中读取记录,因为这允许您从结果集中读取行,然后通过调用NextResult移动到后续的结果集。存储过程中的每个SELECT都会有一个结果集,即使结果集为空

然后将上下文强制转换为IObjectContextAdapter,并调用IObjectContextAdapter.ObjectContext.Translate来创建一个ObjectResult,其中包含从每行创建的对象。要进行此映射,返回的列名必须与其填充的类的属性相匹配

Microsoft示例没有处理其IDisPobles。也许是有原因的

// Just some class with two lists to contain the results.
var result = new ContainsTheResults();

using (var db = new YourDbContext())
{
    using (var cmd = db.Database.Connection.CreateCommand())
    {
        cmd.CommandText = "[dbo].[YourProcedureName]";
        try
        {
            db.Database.Connection.Open();
            using (var reader = cmd.ExecuteReader())
            {

                // Translate the rows in the current result set to a collection of objects
                using (var otherRecords = ((IObjectContextAdapter)db)
                    .ObjectContext
                    .Translate<OtherRecord>(reader, "OtherRecords", MergeOption.AppendOnly))
                {
                    result.OtherRecords = otherRecords.ToList();
                }

                // Go to the next result and read those
                reader.NextResult();
                using (var yetOtherRecords = ((IObjectContextAdapter)db)
                    .ObjectContext
                    .Translate<YetOtherRecord>(reader, "YetOtherRecords", MergeOption.AppendOnly))
                {
                    result.YetOtherRecords = yetOtherRecords.ToList();
                }                     
            }
        }
        finally
        {
            db.Database.Connection.Close();
        }
    }
}

return result;
// Just some class with two lists to contain the results.
var result = new ContainsTheResults();

using (var db = new YourDbContext())
{
    using (var cmd = db.Database.Connection.CreateCommand())
    {
        cmd.CommandText = "[dbo].[YourProcedureName]";
        try
        {
            db.Database.Connection.Open();
            using (var reader = cmd.ExecuteReader())
            {

                // Translate the rows in the current result set to a collection of objects
                using (var otherRecords = ((IObjectContextAdapter)db)
                    .ObjectContext
                    .Translate<OtherRecord>(reader, "OtherRecords", MergeOption.AppendOnly))
                {
                    result.OtherRecords = otherRecords.ToList();
                }

                // Go to the next result and read those
                reader.NextResult();
                using (var yetOtherRecords = ((IObjectContextAdapter)db)
                    .ObjectContext
                    .Translate<YetOtherRecord>(reader, "YetOtherRecords", MergeOption.AppendOnly))
                {
                    result.YetOtherRecords = yetOtherRecords.ToList();
                }                     
            }
        }
        finally
        {
            db.Database.Connection.Close();
        }
    }
}

return result;