ASP.Net:寻找设计视图模型和模型代码的正确方法

时间:2015-12-31 18:22:31

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

我在ASP.Net MVC中相当新。在我的项目中,我没有使用实体框架,而是使用ADO.net。这是我的视图模型设计的代码。请看看。

动作

public class WebGrid_Sample1Controller : Controller
    {
        // GET: WebGrid
        public ActionResult Show1(StudentVm oSVm)
        {
            StudentVm SVm = new StudentVm(); //.GetStudents(oSVm);
            SVm.Students= SVm.GetStudents(oSVm);
            return View(SVm);
        }
    }

我的模型和视图模型代码

public class StudentVm
    {
        public int page { get; set; }
        public int RowCount { get; set; }
        public int PageSize { get; set; }
        public int CurrentPage { get; set; }

        public string sort { get; set; }
        public string sortdir { get; set; }

        public IList<Student> Students { get; set; }

        public StudentVm()
        {
            PageSize = 5;
            sort = "ID";
            sortdir = "ASC";
            CurrentPage = 1;
        }

        public IList<Student> GetStudents(StudentVm oSVm)
        {
            int StartIndex = 0, EndIndex = 0;

            if (oSVm.page == 0)
                oSVm.page = 1;

            StartIndex = ((oSVm.page * oSVm.PageSize) - oSVm.PageSize) + 1;
            EndIndex = (oSVm.page * oSVm.PageSize);
            CurrentPage = StartIndex;

            if (string.IsNullOrEmpty(oSVm.sort))
                oSVm.sort = "ID";

            if (string.IsNullOrEmpty(oSVm.sortdir))
                oSVm.sortdir = "ASC";

            string connectionStringName = System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString;
            IList<Student> _Student = new List<Student>();

            string strSQL = "SELECT ID, FirstName,LastName,IsActive,StateName,CityName FROM vwListStudents WHERE ID >=" + StartIndex + " AND ID <=" + EndIndex;
            strSQL += " ORDER BY " + oSVm.sort + " " + oSVm.sortdir;

            strSQL += ";SELECT COUNT(*) AS Count FROM vwListStudents";
            using (SqlConnection connection = new SqlConnection(connectionStringName))
            {
                SqlCommand command = new SqlCommand(
                  strSQL, connection);

                connection.Open();

                SqlDataReader reader = command.ExecuteReader();

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        _Student.Add(new Student()
                        {
                            ID = Convert.ToInt32(reader["ID"].ToString()),
                            FirstName = reader["FirstName"].ToString(),
                            LastName = reader["LastName"].ToString(),
                            IsActive = Convert.ToBoolean(reader["IsActive"]),
                            StateName = reader["StateName"].ToString(),
                            CityName = reader["CityName"].ToString()
                        });
                    }
                }

                reader.NextResult();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        RowCount = Convert.ToInt32(reader["Count"].ToString());
                    }
                }

                reader.Close();
            }
            //RowCount = _Student.Count;
            return _Student;
        }
    }

模型

public class Student
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsActive { get; set; }
    public string StateName { get; set; }
    public string CityName { get; set; }
}

有人审核我的视图模型代码,并说视图模型不应包含实现。 View Models是在客户端,控制器和View之间传递数据的容器。

他给出了vm code

的新部分设计
public class StudentVm
{
    public int page { get; set; }
    public int RowCount { get; set; }
    public int PageSize { get; set; }
    public int CurrentPage { get; set; }
    public string sort { get; set; }
    public string sortdir { get; set; }
    public IList<Student> Students { get; set; }
}

public class Student
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsActive { get; set; }
    public string StateName { get; set; }
    public string CityName { get; set; }
}

public ActionResult Index()
{
    return View();
}

[HttpPost]
public ActionResult Show1(StudentVm oSVm)
{
    return View(oSVm);
}

所以我的问题是在哪里放置db交互例程?

我在谈论这一行

public IList<Student> GetStudents(StudentVm oSVm)
        {
            int StartIndex = 0, EndIndex = 0;

            if (oSVm.page == 0)
                oSVm.page = 1;

            StartIndex = ((oSVm.page * oSVm.PageSize) - oSVm.PageSize) + 1;
            EndIndex = (oSVm.page * oSVm.PageSize);
            CurrentPage = StartIndex;

            if (string.IsNullOrEmpty(oSVm.sort))
                oSVm.sort = "ID";

            if (string.IsNullOrEmpty(oSVm.sortdir))
                oSVm.sortdir = "ASC";

            string connectionStringName = System.Configuration.ConfigurationManager.ConnectionStrings["StudentDBContext"].ConnectionString;
            IList<Student> _Student = new List<Student>();

            string strSQL = "SELECT ID, FirstName,LastName,IsActive,StateName,CityName FROM vwListStudents WHERE ID >=" + StartIndex + " AND ID <=" + EndIndex;
            strSQL += " ORDER BY " + oSVm.sort + " " + oSVm.sortdir;

            strSQL += ";SELECT COUNT(*) AS Count FROM vwListStudents";
            using (SqlConnection connection = new SqlConnection(connectionStringName))
            {
                SqlCommand command = new SqlCommand(
                  strSQL, connection);

                connection.Open();

                SqlDataReader reader = command.ExecuteReader();

                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        _Student.Add(new Student()
                        {
                            ID = Convert.ToInt32(reader["ID"].ToString()),
                            FirstName = reader["FirstName"].ToString(),
                            LastName = reader["LastName"].ToString(),
                            IsActive = Convert.ToBoolean(reader["IsActive"]),
                            StateName = reader["StateName"].ToString(),
                            CityName = reader["CityName"].ToString()
                        });
                    }
                }

                reader.NextResult();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        RowCount = Convert.ToInt32(reader["Count"].ToString());
                    }
                }

                reader.Close();
            }
            //RowCount = _Student.Count;
            return _Student;
        }

所以我的请求是任何人都可以使用db交互例程重构我的代码。 如何设计整个代码,包括 viewmodel,model和db interaction 例程。我正在使用ADO.Net。到目前为止,我阅读的任何样本文章都使用EF重构我的代码所有项目样本。所以请一些人用db交互例程重构我的代码。提前谢谢。

2 个答案:

答案 0 :(得分:2)

请勿在视图模型中混合使用数据访问代码。这打破了分离关注的整个目的。引入视图模型的整个想法是不要将ORM边实体与视图层混合。

您的视图模型应该是精益平坦的POCO / DTO课程。这些DTO用于在一层到另一层之间传输数据。它不应该知道从哪里获取数据。

您应该有另一个图层/类来为您提供数据,您将把entites映射到您的视图模型。如果您不喜欢进行手动映射,可以使用像Automapper这样的映射库来执行此操作。

您可以根据应用的复杂程度,以多种不同的方式设计应用程序/图层。快速简单的实现就像

YourProject.Common :此项目将DTO的/ POCO存储在您的项目中。如果需要,您可以根据需要保留视图模型。

YourProject.Data :此项目引用了您的Common Project,并以这些DTO类的形式返回数据。

YourProject.Web / UI :您的Web / API项目。这将引用Data项目和Commin项目并调用数据访问方法来获取数据。您可以在此处执行属性映射(从实体读取并设置为查看模型)。

您可以在堆栈中添加更多图层,例如UI和数据访问之间的业务/服务层,以执行一些业务逻辑/映射等。

明智地使用分层,如果你盲目地尝试创建许多真正不需要的层,你最终会弄得一团糟。

答案 1 :(得分:0)

您需要做的第一件事就是将db-access代码从视图模型中移出到存储库类中。请参阅下面的示例:

public class WebGridSampleController
{
    private StudentRepository _data;

    public WebGridSampleController()
    {
        _data = new StudentRepository();
    }

    public ActionResult Show1(StudentVm oSVm)
    {
        var students = _data.GetStudents(oSVm.page, oSVm.pageSize, oSVm.sort, oSVm.sortDir);
        oSVm.Students = students.ToList();
        return View(oSVm);
    }
}

public class StudentRepository
{
    public IEnumerable<Student> GetStudents(int page, int pageSize, string sort, string sortDir)
    {
        // Put the code that you have in StudentVM.GetAllStudents here
    }
}

您发布的代码还有其他问题。我认为大多数都归结为类和变量的不正确命名。例如:这里的视图是什么?它没有查看特定学生的详细信息,是吗?

因此, StudentVm (或 StudentViewModel )应该被命名为 StudentListViewModel 。此外,Controller可能应该命名为 StudentController ,因为它控制着学生的观看。此外,在我看来,行动 Show1 应该被称为 List

考虑到这些因素,可以按如下方式更新示例:

public class StudentController
{
    private StudentRepository _data;

    public StudentController()
    {
        _data = new StudentRepository();
    }

    public ActionResult List(StudentListViewModel viewModel)
    {
        var students = _data.GetStudents(viewModel.Page, viewModel.PageSize, viewModel.Sort, viewModel.SortDirection);
        viewModel.Students = students.ToList();
        return View(viewModel);
    }
}

public class StudentRepository
{
    public IEnumerable<Student> GetStudents(int page, int pageSize, string sort, string sortDir)
    {
        // Put the code that you have in StudentVM.GetAllStudents here
    }
}

我们也可以解决依赖注入的问题,但这似乎在目前推动它有点过分。此外,我不打算在此时为每个“图层”创建一个项目。只需确保您的模型和视图模型不引用任何数据访问内容。