我在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交互例程重构我的代码。提前谢谢。
答案 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
}
}
我们也可以解决依赖注入的问题,但这似乎在目前推动它有点过分。此外,我不打算在此时为每个“图层”创建一个项目。只需确保您的模型和视图模型不引用任何数据访问内容。