簡體   English   中英

ASP.Net:尋找設計視圖模型和模型代碼的正確方法

[英]ASP.Net: Looking for right approach to design view model and model code

我是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模型不應該包含實現。 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交互例程重構我的代碼。 提前致謝。

請勿在視圖模型中混合使用數據訪問代碼。 這打破了分離關注的整個目的。 引入視圖模型的整個想法是不將ORM端實體混合到視圖層。

您的視圖模型應該是精益平坦的POCO / DTO類。 這些DTO用於在一層到另一層之間傳輸數據。 它不應該知道從哪里獲取數據。

您應該有另一個層/類,它將為您提供數據,您將把entites映射到您的視圖模型。 如果您不喜歡手動映射,可以使用像Automapper這樣的映射庫來執行此操作。

您可以根據應用程序的復雜程度以多種不同的方式設計應用程序/層。 快速簡單的實現就像

YourProject.Common :這個項目將DTO的/ POCO存儲在你的項目中。 如果需要,您可以在此處保留您的視圖模型。

YourProject.Data :此項目具有對Common Project的引用,並以這些DTO類的形式返回數據。

YourProject.Web / UI :您的Web / API項目。 這將引用Data項目和Commin項目並調用數據訪問方法來獲取數據。 您可以在此處執行屬性映射(從實體讀取並設置為查看模型)。

您可以向堆棧添加更多層,例如UI和Data Access之間的業務/服務層 ,以執行一些業務邏輯/映射等。

明智地使用分層,如果你盲目地嘗試創建許多真正不需要的層,你最終會弄得一團糟。

您需要做的第一件事是將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
    }
}

我們也可以解決依賴注入的問題,但這似乎在目前推動它有點太過分了。 此外,我不打算在此時為每個“圖層”創建一個項目。 只需確保您的模型和視圖模型不引用任何數據訪問內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM