[英]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.