在.NET Core和Entity Framework中从存储过程返回多个结果集

3

我想从一个返回3个不同表的SQL Server存储过程中加载3个不同的模型,例如:

 select A.id, A.Name from tableA A

 select B.id, B.Age from tableB B

 select C.Test, C.Param from tableC C

通常情况下,我会像这样使用Entity Framework Core处理单个结果的存储过程:
上下文:
 public virtual DbQuery<StoredProcedureModel> spModel{ get; set; }

 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
        modelBuilder.Query<StoredProcedureModel>(entity =>
        {
            entity.Property(e => e.Id)
                    .HasColumnName("Id");
            entity.Property(e => e.Name)
                    .HasColumnName("Name");
        }
 }

仓库:

return _context.StoredProcedureModel
        .FromSql<StoredProcedureModel>(
            "GET_ID_NAME @ID,@NAME",
            new SqlParameter("@ID", ID),
            new SqlParameter("@NAME", Name))
        .ToList();

这只是一个虚拟示例,但我想知道是否有一种方法可以将所有3个表加载到3个不同的模型中(返回的某些表具有相同的列名,例如“id”)。


1
暂时不支持(尚未)。 - Ivan Stoev
请查看功能请求支持多个结果集-GitHub - Gert Arnold
1个回答

8

目前使用Entity Framework不可能做到,但是有一个功能请求。 作为解决方法,根据这篇博客文章,可以使用ADO.Net解决:

首先编写你的类:

public class TableA 
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class TableB
{
    public int Id { get; set; }
    public int Age { get; set; }
}

public class TableC
{
    public string Test { get; set; }
    public string Param { get; set; }
}

public class StoredProcedureResult
{
    public List<TableA> TableAEntries { get; set; }
    public List<TableB> TableBEntries { get; set; }
    public List<TableC> TableCEntries { get; set; }
}

接下来将以下功能代码编写到CustomDbContext类中:

public async Task<StoredProcedureResult> GetStoredProcedureResult(int id, string name)
{
    var connection = Database.GetDbConnection();
    await connection.OpenAsync();

    var command = connection.CreateCommand();
    command.CommandText = "GET_ID_NAME @ID, @NAME";
    command.CommandType = CommandType.StoredProcedure;

    command.Parameters.Add(new Microsoft.Data.SqlClient.SqlParameter("@ID", id));
    command.Parameters.Add(new Microsoft.Data.SqlClient.SqlParameter("@NAME", name));

    var reader = await command.ExecuteReaderAsync();
    var tableAEntries = new List<TableA>();
    var tableBEntries = new List<TableB>();
    var tableCEntries = new List<TableC>();

    while (await reader.ReadAsync())
    {
        tableAEntries.Add(new TableA
        {
            Id = reader.GetInt32("id"),
            Name = reader.GetString("name"),
        });
    }

    await reader.NextResultAsync();

    while (await reader.ReadAsync())
    {
        tableBEntries.Add(new TableB
        {
            Id = reader.GetInt32("id"),
            Age = reader.GetInt32("Age"),
        });
    }

    await reader.NextResultAsync();

    while (await reader.ReadAsync())
    {
        tableCEntries.Add(new TableC
        {
            Test = reader.GetString("Test"),
            Param = reader.GetString("Param"),
        });
    }

    var storedProcedureResult = new StoredProcedureResult();

    storedProcedureResult.TableAEntries = tableAEntries;
    storedProcedureResult.TableBEntries = tableBEntries;
    storedProcedureResult.TableCEntries = tableCEntries;

    await reader.CloseAsync();

    return storedProcedureResult;
}

1
严格来说,那不是一个Entity-Framework解决方案。它是ADO.Net。问题是是否有本地支持就像EF6中一样 - Gert Arnold
谢谢@GertArnold,我会更新我的答案,指出它是使用ADO.Net而不是Entity Framework的解决方案。 - Matthias Müller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接