<small id='3kMKA'></small><noframes id='3kMKA'>

      • <bdo id='3kMKA'></bdo><ul id='3kMKA'></ul>
    1. <i id='3kMKA'><tr id='3kMKA'><dt id='3kMKA'><q id='3kMKA'><span id='3kMKA'><b id='3kMKA'><form id='3kMKA'><ins id='3kMKA'></ins><ul id='3kMKA'></ul><sub id='3kMKA'></sub></form><legend id='3kMKA'></legend><bdo id='3kMKA'><pre id='3kMKA'><center id='3kMKA'></center></pre></bdo></b><th id='3kMKA'></th></span></q></dt></tr></i><div id='3kMKA'><tfoot id='3kMKA'></tfoot><dl id='3kMKA'><fieldset id='3kMKA'></fieldset></dl></div>
      <legend id='3kMKA'><style id='3kMKA'><dir id='3kMKA'><q id='3kMKA'></q></dir></style></legend>
      <tfoot id='3kMKA'></tfoot>

      在 .net 核心中使用多个结果集

      时间:2023-07-12
    2. <small id='7Ax4T'></small><noframes id='7Ax4T'>

        <tfoot id='7Ax4T'></tfoot>
      • <legend id='7Ax4T'><style id='7Ax4T'><dir id='7Ax4T'><q id='7Ax4T'></q></dir></style></legend>
            <bdo id='7Ax4T'></bdo><ul id='7Ax4T'></ul>

              <tbody id='7Ax4T'></tbody>

            <i id='7Ax4T'><tr id='7Ax4T'><dt id='7Ax4T'><q id='7Ax4T'><span id='7Ax4T'><b id='7Ax4T'><form id='7Ax4T'><ins id='7Ax4T'></ins><ul id='7Ax4T'></ul><sub id='7Ax4T'></sub></form><legend id='7Ax4T'></legend><bdo id='7Ax4T'><pre id='7Ax4T'><center id='7Ax4T'></center></pre></bdo></b><th id='7Ax4T'></th></span></q></dt></tr></i><div id='7Ax4T'><tfoot id='7Ax4T'></tfoot><dl id='7Ax4T'><fieldset id='7Ax4T'></fieldset></dl></div>

              • 本文介绍了在 .net 核心中使用多个结果集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                问题描述

                在使用存储过程检索结果时,如何在 .net 核心的视图模型中检索和存储多个结果集

                While retrieving the results using stored procedure how can I retrieve and store multiple result set in view model in .net core

                例如从存储过程中,我返回以下两个查询的记录

                For e.g. from stored procedure I am returning records for below two queries

                Select * LMS_Survey
                Select * from LMS_SurveyQuestion
                Select * from LMS_SurveyQuestionOptionChoice
                

                下面是两个表的视图模型

                and below is view model for two tables

                public class LMS_SurveyTraineeViewModel
                {
                    public LMS_SurveyDetailsViewModel SurveyDetailsViewModel { get; set; }
                    public LMS_SurveyQuestionsViewModel SurveyQuestionsViewModel { get; set; }
                    public LMS_SurveyQuestionOptionChoiceViewModel SurveyQuestionOptionChoiceViewModel { get; set; }
                }
                

                这就是我执行存储过程的方式

                This is how I am executing the stored procedure

                public List<LMS_SurveyTraineeViewModel> GetTraineeSurvey(int surveyID)
                        {
                            try
                            {
                                List<LMS_SurveyTraineeViewModel> modelList = new List<LMS_SurveyTraineeViewModel>();
                
                                modelList = dbcontext.Set<LMS_SurveyTraineeViewModel>().FromSql("LMSSP_GetTraineeSurvey @surveyID = {0},@LanguageID = {1}", surveyID, AppTenant.SelectedLanguageID).ToList();
                
                                return modelList;
                            }
                            catch (Exception ex)
                            {
                                throw ex;
                            }
                        }
                

                如何在视图模型中使用存储过程存储多个结果集?

                How can stored the multiple result set using stored procedure in view model ?

                推荐答案

                目前,EF Core 不支持这个.有一个未解决的问题可以解决.

                Currently, EF Core doesn't not support this. There is an open issue to address this.

                https://github.com/aspnet/EntityFramework/issues/8127

                2018 年 9 月 12 日更新:即使对于 3.0 版,这仍然不是 EF Core 的优先事项;因此,当您有多个结果场景时,最好使用 Dapper 或普通 ADO.NET

                Update 12th Sep 2018: This is still not a priority for EF Core even for release 3.0; so best use Dapper or plain ADO.NET when you have multiple results scenario

                2020 年 6 月 25 日更新:即使是 5.0 版,EF Core 仍处于积压状态;因此,当您有多个结果场景时,最好使用 Dapper 或普通 ADO.NET

                Update 25th Jun 2020: still on the backlog for EF Core even for release 5.0; so best use Dapper or plain ADO.NET when you have multiple results scenario

                2021 年 2 月 7 日更新: EF Core 仍在积压中

                Update 7th Feb 2021: still on the backlog for EF Core

                在此期间,GitHub 问题上发布了一个出色的解决方案,供任何通过扩展方法寻找替代方案的人使用

                public static async Task<IList<IList>> MultiResultSetsFromSql(this DbContext dbContext, ICollection<Type> resultSetMappingTypes, string sql, params object[] parameters)
                {
                    var resultSets = new List<IList>();
                
                    var connection = dbContext.Database.GetDbConnection();
                    var parameterGenerator = dbContext.GetService<IParameterNameGeneratorFactory>()
                                                        .Create();
                    var commandBuilder = dbContext.GetService<IRelationalCommandBuilderFactory>()
                                                    .Create();
                
                    foreach (var parameter in parameters)
                    {
                        var generatedName = parameterGenerator.GenerateNext();
                        if (parameter is DbParameter dbParameter)
                            commandBuilder.AddRawParameter(generatedName, dbParameter);
                        else
                            commandBuilder.AddParameter(generatedName, generatedName);
                    }
                
                    using var command = connection.CreateCommand();
                    command.CommandType = CommandType.Text;
                    command.CommandText = sql;
                    command.Connection = connection;
                    for (var i = 0; i < commandBuilder.Parameters.Count; i++)
                    {
                        var relationalParameter = commandBuilder.Parameters[i];
                        relationalParameter.AddDbParameter(command, parameters[i]);
                    }
                
                    var materializerSource = dbContext.GetService<IEntityMaterializerSource>();
                    if (connection.State == ConnectionState.Closed)
                        await connection.OpenAsync();
                
                    using var reader = await command.ExecuteReaderAsync();
                    foreach (var pair in resultSetMappingTypes.Select((x, i) => (Index: i, Type: x)))
                    {
                        var i = pair.Index;
                        var resultSetMappingType = pair.Type;
                        if (i > 0 && !(await reader.NextResultAsync()))
                            throw new InvalidOperationException(string.Format("No result set at index {0}, unable to map to {1}.", i, resultSetMappingType));
                
                        var type = resultSetMappingType;
                        var entityType = dbContext.GetService<IModel>()
                                                    .FindEntityType(type);
                        if (entityType == null)
                            throw new InvalidOperationException(string.Format("Unable to find a an entity type (or query type) matching '{0}'", type));
                        var relationalTypeMappingSource = dbContext.GetService<IRelationalTypeMappingSource>();
                        var columns = Enumerable.Range(0, reader.FieldCount)
                                                .Select(x => new
                                                {
                                                    Index = x,
                                                    Name = reader.GetName(x)
                                                })
                                                .ToList();
                        var relationalValueBufferFactoryFactory = dbContext.GetService<IRelationalValueBufferFactoryFactory>();
                        int discriminatorIdx = -1;
                        var discriminatorProperty = entityType.GetDiscriminatorProperty();
                        var entityTypes = entityType.GetDerivedTypesInclusive();
                
                        var instanceTypeMapping = entityTypes.Select(et => new
                        {
                            EntityType = et,
                            Properties = et.GetProperties()
                                            .Select(x =>
                                            {
                                                var column = columns.FirstOrDefault(y => string.Equals(y.Name,
                                                                                                        x.GetColumnName() ?? x.Name, StringComparison.OrdinalIgnoreCase)) ?? throw new InvalidOperationException(string.Format("Unable to find a column mapping property '{0}'.", x.Name));
                
                                                if (x == discriminatorProperty)
                                                    discriminatorIdx = column.Index;
                                                return new TypeMaterializationInfo(x.PropertyInfo.PropertyType, x, relationalTypeMappingSource, column.Index);
                                            })
                                            .ToArray()
                        })
                        .Select(x => new
                        {
                            EntityType = x.EntityType,
                            Properties = x.Properties,
                            ValueBufferFactory = relationalValueBufferFactoryFactory.Create(x.Properties)
                        })
                        .ToDictionary(e => e.EntityType.GetDiscriminatorValue() ?? e.EntityType, e => e)
                        ;
                
                        var resultSetValues = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
                        while (await reader.ReadAsync())
                        {
                            var instanceInfo = discriminatorIdx < 0 ? instanceTypeMapping[entityType] : instanceTypeMapping[reader[discriminatorIdx]];
                
                            var valueBuffer = instanceInfo.ValueBufferFactory.Create(reader);
                
                            var materializationAction = materializerSource.GetMaterializer(instanceInfo.EntityType);
                            resultSetValues.Add(materializationAction(new MaterializationContext(valueBuffer, dbContext)));
                        }
                
                        resultSets.Add(resultSetValues);
                    }
                
                    return resultSets;
                }
                

                以及扩展类型的方法

                public static async Task<(IReadOnlyCollection<T1> FirstResultSet, IReadOnlyCollection<T2> SecondResultSet)> MultiResultSetsFromSql<T1, T2>(this DbContext dbContext, string sql, params object[] parameters)
                {
                    var resultSetMappingTypes = new[]
                                                {
                                                        typeof(T1), typeof(T2)
                                                };
                
                    var resultSets = await MultiResultSetsFromSql(dbContext, resultSetMappingTypes, sql, parameters);
                
                    return ((IReadOnlyCollection<T1>)resultSets[0], (IReadOnlyCollection<T2>)resultSets[1]);
                }
                
                public static async Task<(IReadOnlyCollection<T1> FirstResultSet, IReadOnlyCollection<T2> SecondResultSet, IReadOnlyCollection<T3> ThirdResultSet)> MultiResultSetsFromSql<T1, T2, T3>(this DbContext dbContext, string sql, params object[] parameters)
                {
                    var resultSetMappingTypes = new[]
                                                {
                                                        typeof(T1), typeof(T2), typeof(T3)
                                                };
                
                    var resultSets = await MultiResultSetsFromSql(dbContext, resultSetMappingTypes, sql, parameters);
                
                    return ((IReadOnlyCollection<T1>)resultSets[0], (IReadOnlyCollection<T2>)resultSets[1], (IReadOnlyCollection<T3>)resultSets[2]);
                }
                

                这篇关于在 .net 核心中使用多个结果集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                上一篇:ASP.NET 5 中所有类型的 http 标头都去了哪里? 下一篇:是否可以从 wwwroot 文件夹外部提供静态文件?

                相关文章

                <legend id='rSHx3'><style id='rSHx3'><dir id='rSHx3'><q id='rSHx3'></q></dir></style></legend>

                <small id='rSHx3'></small><noframes id='rSHx3'>

              • <tfoot id='rSHx3'></tfoot>

              • <i id='rSHx3'><tr id='rSHx3'><dt id='rSHx3'><q id='rSHx3'><span id='rSHx3'><b id='rSHx3'><form id='rSHx3'><ins id='rSHx3'></ins><ul id='rSHx3'></ul><sub id='rSHx3'></sub></form><legend id='rSHx3'></legend><bdo id='rSHx3'><pre id='rSHx3'><center id='rSHx3'></center></pre></bdo></b><th id='rSHx3'></th></span></q></dt></tr></i><div id='rSHx3'><tfoot id='rSHx3'></tfoot><dl id='rSHx3'><fieldset id='rSHx3'></fieldset></dl></div>
                  • <bdo id='rSHx3'></bdo><ul id='rSHx3'></ul>