【问题标题】:Optimizing C# code in MVC controller在 MVC 控制器中优化 C# 代码
【发布时间】:2010-05-22 14:42:07
【问题描述】:

我正在制作许多不同的控制器,其中一个与数据库中的每个存储过程相关。这些仅用于读取数据并使它们以 JSON 格式提供给 javascripts。

到目前为止,我的代码看起来像这样,我想知道我是否错过了任何重用代码的机会,也许可以做一些帮助类。我在做 OOP 方面的经验太少,因此非常感谢这里的任何帮助和建议。

到目前为止,这是我的通用代码(经过测试且有效);

using System;
using System.Configuration;
using System.Web.Mvc;
using System.Data;
using System.Text;
using System.Data.SqlClient;
using Prototype.Models;

namespace Prototype.Controllers
{
    public class NameOfStoredProcedureController : Controller
    {

        char[] lastComma = { ',' };

        String oldChar = "\"";
        String newChar = """;

        StringBuilder json = new StringBuilder();

        private String strCon = ConfigurationManager.ConnectionStrings["SomeConnectionString"].ConnectionString;
        private SqlConnection con;

        public StoredProcedureController()
        {
            con = new SqlConnection(strCon);
        }

        public string do_NameOfStoredProcedure(int parameter)
        {
            con.Open();

            using (SqlCommand cmd = new SqlCommand("NameOfStoredProcedure", con))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@parameter", parameter);


                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        json.AppendFormat("[{0},\"{1}\"],", reader["column1"], reader["column2"]);
                    }
                }
                con.Close();
            }

            if (json.Length.ToString().Equals("0"))
            {
                return "[]";
            }

            else
            {
                return "[" + json.ToString().TrimEnd(lastComma) + "]";
            }
        }


        //http://host.com/NameOfStoredProcedure?parameter=value
        public ActionResult Index(int parameter)
        {
            return new ContentResult
            {
                ContentType = "application/json",
                Content = do_NameOfStoredProcedure(parameter)
            };
        }
    }
}

【问题讨论】:

    标签: c# .net asp.net-mvc asp.net-mvc-2


    【解决方案1】:

    我可能不会直接从控制器访问数据库,而是将这种访问抽象化。不是真正的性能优化,而是设计改进。所以首先定义一个模型来保存存储过程的结果:

    public class MyModel
    {
        public string Column1 { get; set; }
        public string Column2 { get; set; }
    }
    

    然后定义一个存储库接口,该接口将包含此模型上的不同操作:

    public interface IRepository
    {
        IEnumerable<MyModel> GetModel(int id);
    }
    

    接下来实现存储库:

    public class RepositorySql : IRepository
    {
        public IEnumerable<MyModel> GetModel(int id)
        {
            using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["SomeConnectionString"].ConnectionString))
            using (var cmd = conn.CreateCommand())
            {
                conn.Open();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "NameOfStoredProcedure";
                cmd.Parameters.AddWithValue("@parameter", id);
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        yield return new MyModel
                        {
                            Column1 = reader["column1"].ToString(),
                            Column2 = reader["column2"].ToString()
                        };
                    }
                }
            }
        }
    }
    

    最后你的控制器将使用存储库:

    public class NameOfStoredProcedureController : Controller
    {
        private readonly IRepository _repository;
        public NameOfStoredProcedureController(IRepository repository)
        {
            _repository = repository;
        }
    
        // Warning don't add this constructor. Use a DI framework instead.
        // This kind of constructors are called Poor Man DI (see http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/07/03/how-not-to-do-dependency-injection-in-nerddinner.aspx)
        // for more info on why this is bad.
        public NameOfStoredProcedureController() : this(new RepositorySql())
        { }
    
        public ActionResult Index(int parameter)
        {
            var model = _repository.GetModel(parameter);
            // Use directly Json, no need to do the serialization manually
            return Json(model);
        }
    }
    

    【讨论】:

    • 这看起来像可靠的代码,但是重用的问题是每个控制器可能依赖于各种类型和数量的输入参数,以及各种不同数量和类型的输出列。你有解决方案吗?另外我真的很想知道你为什么不直接从控制器访问数据库,主要是因为面向对象不好?
    • 如果这些列和参数有共同点,请定义相互派生的输入和输出模型,以便您拥有一个不错的对象模型。不要考虑数据库列:考虑实体和这些实体之间的关系并编写类来表示它们。至于为什么直接从控制器访问数据库不好,答案是你的控制器与这个特定的实现绑定在一起,不可能单独进行单元测试。
    • 太棒了。感谢您花时间帮助我解决这个问题。很棒。
    【解决方案2】:

    我经常自己手动做事,但你看过JsonResultExample)吗?

    还有JavaScriptSerializer?

    还有JSON.Net?

    【讨论】:

    • 我有,但我发现当我需要自定义 json 格式时,只使用 stringbuilder 是最简单的(虽然是的,有点难看的代码)。不过,这些仍然与问题相关,谢谢您指出。希望它对阅读本文的其他人有用。
    • 我明白了,我有时也使用 stringbuilder 方法。
    猜你喜欢
    • 2017-10-14
    • 2012-11-13
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多