从返回多个实际表的复杂存储过程中检索 asp.net MVC 中的数据

Posted

技术标签:

【中文标题】从返回多个实际表的复杂存储过程中检索 asp.net MVC 中的数据【英文标题】:Retrieve data in asp.net MVC from complex stored procedure which return multiple actual table 【发布时间】:2022-01-20 08:57:30 【问题描述】:

返回多个实际表作为结果集的用户定义存储过程。

CREATE  PROCEDURE uspDemo(
@UserID BIGINT=0,
 @IsAdmin bit=0,
 @Title varchar(120)=''
)AS
BEGIN 
------Retrieve Posts------

SELECT * FROM tblPost AS MP INNER JOIN tblUserProfile AS UP ON UP.ID=MP.UserID
WHERE UP.ID=@UserID AND ((@IsAdmin=0 AND MP.IsDeleted=0 AND MP.IsApproved=1)OR (@IsAdmin=1 OR MP.IsDeleted=0 OR MP.IsApproved=1))

----- Retrieve Tags------

SELECT *  FROM tblTagMasters AS MT INNER JOIN tblPostTags AS MP ON MT.TagID= MP.TagID

--------Retrieve User likes-----

SELECT * FROM tblUserLikes AS UV INNER JOIN tblPost AS MP ON MP.PostId=UV.PostId

END

我想根据asp.net MVC中的模型将存储过程返回的所有实际表的列表格式转换为列表格式。

 public List<PostView> GetPosts(int userID = 0, string s = "")
    
        IEnumerable<PostView> query = null;
        using (var db = new MVCDatabase())
        
            var cmd = db.Database.Connection.CreateCommand();
            cmd.CommandText = "[dbo].[uspDemo]";
            cmd.CommandType = CommandType.StoredProcedure;                             
            cmd.Parameters.Add(new SqlParameter("@UserID", userID));
            cmd.Parameters.Add(new SqlParameter("@IsAdmin", 0));                
            cmd.Parameters.Add(new SqlParameter("@Title", s));
            try
            
                db.Database.Connection.Open();
                
                using (var result = cmd.ExecuteReader())
                
                    var Posts = ((IObjectContextAdapter)db).ObjectContext.Translate<PostView>(result).ToList();
                    result.NextResult();
                    var tags = ((IObjectContextAdapter)db).ObjectContext.Translate<TagView>(result).ToList();
                    result.NextResult();
                    var uservotes = ((IObjectContextAdapter)db).ObjectContext.Translate<UserVoteView>(result).ToList();
                    Posts.ForEach(z =>
                    
                        z.TagMaster = tags.Where(x => x.PostId == z.PostId).ToList();
                        z.UserLike = uservotes.Where(x => x.PostId == z.PostId).ToList();

                    );
                    query = Posts;
                
            
            catch (Exception ex)
            
                MSError.Trace(ex);
            
            finally
            
                db.Database.Connection.Close();
                cmd.Dispose();
            
            return query.ToList();
        
    

抛出 ArgumentNullException

帮我找出解决办法。

【问题讨论】:

使用ado.netDataset 获取多个表。然后您可以将dataset 转换为datatableListLINQ 但是,我想将`结果`翻译成模型,然后转换成列表。那我该怎么办。 你可以使用 AutoMapper 之类的东西。否则,您将不得不遍历(对于每个)结果集(帖子)并将项目添加到 IEnumerable 查询中。 【参考方案1】:

这是一个演示如何做到这一点。使用System.dataSystem.Linq 你可以在下面做。

        var cmd = db.Database.Connection.CreateCommand();
        cmd.CommandText = "[dbo].[uspDemo]";
        cmd.CommandType = CommandType.StoredProcedure;                             
        cmd.Parameters.Add(new SqlParameter("@UserID", userID));
        cmd.Parameters.Add(new SqlParameter("@IsAdmin", 0));                
        cmd.Parameters.Add(new SqlParameter("@Title", s));

        SqlDataAdapter da = new SqlDataAdapter(); //adapter
        DataSet ds = new DataSet(); //dataset
        cmd.CommandType = CommandType.StoredProcedure;
        da = new SqlDataAdapter(cmd);
        da.Fill(ds);  //fill dataset with multiple select


        var Posts = (from DataRow row in ds.Tables[0].Rows  //0 means 1st select
                           select new Posts  //Posts model to map
                           
                               test = row["test"].ToString(), //test is the column name from select
                               test1 = Convert.ToDecimal(row["test1"])
                           ).ToList();

        var Tags = (from DataRow row in ds.Tables[1].Rows //1 means 2nd select
                           select new Tags //Tags model to map
                           
                               test = row["test"].ToString(), //test is the column name from select
                               test1 = Convert.ToDecimal(row["test1"])
                           ).ToList();
        var User  = (from DataRow row in ds.Tables[2].Rows //2 means 3rd select
                           select new User //User model to map
                           
                               test = row["test"].ToString(), //test is the column name from select
                               test1 = Convert.ToDecimal(row["test1"])
                           ).ToList();

【讨论】:

如果我们不想一一读取数据,那么我应该怎么做才能转换为表格列表。 那么你需要EntityFramework。并关注此Link 了解更多详情。单选非常简单,但多选需要一些解决方法。

以上是关于从返回多个实际表的复杂存储过程中检索 asp.net MVC 中的数据的主要内容,如果未能解决你的问题,请参考以下文章

传递参数以返回存储过程的复杂结果

Apache DbUtils:处理从存储过程返回的多个结果集

从存储过程中检索数据

如何从 SQL Server 中的存储过程中检索参数列表

视图和存储过程

如何使用 FromSqlRaw Entity Framework Core 3.1 从存储过程中返回多个 SELECT 集