【问题标题】:Newbie ASP.NET MVC 5 Model stored procedure heavy backend advice新手 ASP.NET MVC 5 模型存储过程重后端建议
【发布时间】:2016-04-19 04:25:26
【问题描述】:

我有一个企业应用程序严重依赖存储过程来实现业务逻辑。我正在考虑将前端从 Webforms 重做为 ASP.NET MVC,但我希望不必为每个存储过程(有数百个)编写模型。通常,“Get”存储过程与等效的“set”存储过程没有相同的参数,并且通常单个存储过程正在更新多个数据库表。

所以我的问题是在这种后端构建 ASP.NET MVC 应用程序的最佳实践是什么?实体框架会为此工作吗?我肯定希望我不必为每个存储过程构建 100 个模型,一个或两个...

我还在研究仅使用带有 webdata 的动态数据行模型的普通剃须刀网页,它可能更合适。但是我不能这么多地使用剑道 UI 之类的简洁的东西(我认为)。

提前感谢您的智慧。

【问题讨论】:

  • 所以,从您的问题来看,听起来您正在规划一个架构,但不清楚应用程序的功能、当前架构是什么以及对架构或技术堆栈的要求是什么。你希望通过这次重写实现什么?预算是多少小时?
  • 恕我直言,ASP.Net 就是 ASP.Net - 根据您当前在 WebForms 中处理数据的方式,您可以尝试(简单地)将 MVCWebPages 视为“前端” "(使用 WebForms 中当前存在的任何数据库调用/基础设施)。但是,如果您还考虑重做现有的数据基础架构,那么 DonO 的答案是他们要走的路(服务层,EF 与否)。

标签: c# asp.net-mvc asp.net-mvc-4 razor


【解决方案1】:

Entity Framework 将帮助您解决这个问题。我建议先从数据库中编写代码。我不推荐使用 MVC 和 Razor。我只想为业务逻辑构建一个库层(该层将使用您的存储过程)和用于通信的服务层(该层将仅处理与客户端的通信,并将使用该库来获取或设置数据)。对于客户端,我会使用纯 HTML 和 JavaScript,并使用 Ajax 调用来使用服务。

如果您的公司有支持 Web 套接字的服务器,我什至会使用 SignalR 集线器而不是 WebApi 作为服务层。

【讨论】:

  • ++ 用于激进的方法。实际上,我有一个 API 大部分已经构建出来,我可以通过 ajax 调用访问它。我可能会在没有 MVC 的情况下使用剃须刀,因为我可能还无法完全切断服务器端的电源线。 SignalR 玩起来可能很有趣,但可能会超过我想做的 90% 的事情。我只需要找到一个好的 UI 包来支持主题化。今天可以看看。如果不是太多的痛苦,阿吉拉尔也可能是好的。
  • *Angular...拼写不是我的任务
【解决方案2】:

您不需要为每个存储过程创建一个模型。

这一切都取决于你想做什么。

当我使用存储过程将数据保存到数据库时,我会为每个要保存的值发送参数。

从 db 获取值时,我使用模型。您在这里使用的模型显然取决于您,如果您正在接收文件数据,那么您可以拥有 FileModel、imageData、ImageModel 等。

例子:

我为此使用管理器和服务类:

public void UpdateCustomerCredentials(long id, string firstName, string lastName, string email, string mobilePhoneNumber, int price, string notes, Guid? imageId = null)
{
    using (SqlConnection con = new SqlConnection(ConnectionString))
    {
        using (SqlCommand cmd = new SqlCommand("UpdateCustomer", con))
        {

            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("@Id", id));
            cmd.Parameters.Add(new SqlParameter("@FirstName", firstName));
            cmd.Parameters.Add(new SqlParameter("@LastName", lastName));
            cmd.Parameters.Add(new SqlParameter("@Email", email));
            cmd.Parameters.Add(new SqlParameter("@MobilePhoneNumber", mobilePhoneNumber));
            cmd.Parameters.Add(new SqlParameter("@ImageId", GetParamValue(imageId)));
            cmd.Parameters.Add(new SqlParameter("@Price", price));
            cmd.Parameters.Add(new SqlParameter("@Notes", notes));

            try
            {
                con.Open();

                cmd.ExecuteReader();

                con.Close();
            }
            catch (SqlException ex)
            {
                cmd.Dispose();
                throw ex;
            }

            finally
            {
                cmd.Dispose();
            }
        }
    }
}

使用客户模型获取数据:

    public List<Customer> GetAllCustomers()
    {
        List<Customer> customers;
        SqlDataReader sqlDataReader = null;

        using (SqlConnection con = new SqlConnection(ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand("GetAllCustomers", con))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                try
                {
                    con.Open();

                    sqlDataReader = cmd.ExecuteReader();

                    customers = (from x in sqlDataReader.Cast<DbDataRecord>()
                                 select new Customer
                                 {
                                     Id = GetValue<long>("Id", x),
                                     ProfileImageId = GetValue<Guid?>("ImageId", x),
                                     ContentType = GetValue<string>("ContentType", x),
                                     FirstName = GetValue<string>("Name", x),
                                     LastName = GetValue<string>("LastName", x),
                                     Email = GetValue<string>("Email", x),
                                     PhoenNumber = GetValue<string>("MobilePhoneNumber",x)

                                 }).ToList();

                    sqlDataReader.Close();
                }

                catch (SqlException ex)
                {
                    if (sqlDataReader != null) sqlDataReader.Close();

                    cmd.Dispose();

                    throw ex;
                }

                finally
                {
                    if (sqlDataReader != null) sqlDataReader.Dispose();

                    cmd.Dispose();
                }

            }


        }

        return customers;
    }

我个人喜欢使用 classLibraries 进行 SQL 调用。这可能超出了您的问题,而是个人喜好。

就实体框架而言,我缺乏经验,但我认为实体框架 + 存储过程是一个坏主意。

希望这能让你更清楚

【讨论】:

  • 很好的答案,但看起来我将不得不建立模型。从某种意义上说,这可能不是一件坏事,但这是相当多的工作。正在考虑动态创建扩展类,但不确定是否可以节省我的工作。感谢你的回答。如果在一天结束时没有其他人能更好地参与进来,我会感谢你的答案。
  • 很乐意提供帮助:)。作为一个额外的说明,无论您选择这样做,它都会涉及大量的工作,如果这是最节省您工作的方式可能不是,但我相信这是处理存储过程和 MVC 的好方法
猜你喜欢
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 1970-01-01
  • 2020-08-10
  • 2023-04-05
  • 2017-04-30
相关资源
最近更新 更多