当前结构MVVC
总结:
Controller(接受请求,返回View)
View(前端页面,一个viewmodel(看做var data)对应一个View)
Model(对于数据库中表基本操作而生成的很纯净的类)
ViewModel(强类型视图,相当于ashx nvelocity里的 var data匿名类,所以一个viewmodel对应一个view)
BusinessLayer(涉及到对于Model里对象进行进一步处理,生成对应的ViewModel再由controller return(view,viewmodel))
DataAccessLayer 与数据库直接通信,通过在其中new实体获得数据库上下文dbcontext(或db),再编写linq(linq语句中会用到dbcontext),来获取数据集合
- BSL与DAL的区别是什么呢?我觉得最大得是DAL是直接与数据库打交道,通过linq获取相应的数据,当然linq可能写的胡里花哨但相对来说比较原始;而BSL负责接收DAL对应数据进一步处理。最好是直接返回ViewModel需要的数据,这样将会使controller更纯净
和ashx nvelocity进行对比,其实挺容易理解的,重点是把ViewModel之于View 类比为var data 之于渲染的那个页面。
MVC
return View("myView",employeeViewModel);
ashx
var data = {data = ....} String html = commonHelper.RenderHtml("test.html",data)
- 模板语法。默认是Razor 但是Nvelocity也能用,个人感觉Razor语法比nvelocity复杂,功能也应该全面一些
- View中若使用强类型视图即ViewModel记得在头部加:
@using Webapplication. ... @model xxxViewModel
数据访问层 EF框架
简述实体框架(EF)
EF是一种ORM工具,ORM表示对象关联映射。
在RDMS中,对象称为表格和列对象,而在.net中(面向对象)称为类,对象以及属性。
任何数据驱动的应用实现的方式有两种:
1. 通过代码与数据库关联(称为数据访问层或数据逻辑层)
2. 通过编写代码将数据库数据映射到面向对象数据,或反向操作。
ORM是一种能够自动完成这两种方式的工具。EF是微软的ORM工具。
什么是代码优先的方法?
EF提供了三种方式来实现项目:
l 数据库优先方法——创建数据库,包含表,列以及表之间的关系等,EF会根据数据库生成相应的Model类(业务实体)及数据访问层代码。
l 模型优先方法——模型优先指模型类及模型之间的关系是由Model设计人员在VS中手动生成和设计的,EF将模型生成数据访问层和数据库。
l 代码优先方法——代码优先指手动创建POCO类。这些类之间的关系使用代码定义。当应用程序首次执行时,EF将在数据库服务器中自动生成数据访问层以及相应的数据库。
什么是POCO类?
POCO即Plain Old CLR对象,POCO类就是已经创建的简单.Net类。在上两节的实例中,Employee类就是一个简单的POCO类。
实际操作
实验八(EF 代码优先)
- 此次又添加了DataAccessLayer,在里边新建了SalesERPDAL类,继承了Dbcontext类,并重写了其中的OnModelCreating方法,达到的效果就是在数据库里自动建了一张表,表名TblEmployee,列名是根据model里的employee类生成的。
public class SalesERPDAL:DbContext { public DbSet<Employee> Employees { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Employee>().ToTable("TblEmployee"); base.OnModelCreating(modelBuilder); } }
- 所以相应的改动就发生在了BS层上,通过调用DAL层,利用ToList方法直接获得数据库中所有employee。之后再由controller调用。
public class employeesBSL { public List<Employee> GetEmployees() { //List<Employee> emps = new List<Employee>(); //Employee emp1 = new Employee(); //emp1.FirstName = "DJ"; //emp1.LastName = "Snake"; //emp1.Salary = -1; //emps.Add(emp1); //Employee emp2 = new Employee(); //emp2.FirstName = "FK"; //emp2.LastName = "lalake"; //emp2.Salary = 21; //emps.Add(emp2); //Employee emp3 = new Employee(); //emp3.FirstName = "DK"; //emp3.LastName = "lightke"; //emp3.Salary = -1; //emps.Add(emp3); SalesERPDAL salesDal = new SalesERPDAL(); return salesDal.Employees.ToList() ; } }
- EF框架连数据库的连接字符串写法注意,此处因为连接字符串的name与DAL层的SalesEPRDal相同,所以数据库和SalesDal可以直接通信
<connectionStrings> <!--<add name="connstr" connectionString="Data Source=LENOVO-PC\SQLEXPRESS01;Initial Catalog=schoolManagement;Persist Security Info=True;User ID=sa;Password=12345;"></add>--> <add connectionString="Data Source=LENOVO-PC\SQLEXPRESS01;Initial Catalog=SalesERPDB;Integrated Security=True;User ID=sa;Password=12345;" name="SalesERPDAL" providerName="System.Data.SqlClient"/> </connectionStrings>
- 感觉以上由Employee类来生成数据库表的方法并不常用。
插一个,《七天》系列并没有介绍数据库优先的相关内容,所以此处插一些从其他地方找来的关于数据库优先的内容
找到了一个数据库优先的相关文章在收藏里,主要讲的从数据库映射过来的阶段,下面贴一个用
ef(dbcontext)进行查询,有部分Linq 的文章一共分为三篇
第一篇:http://www.cnblogs.com/telon/p/4092869.html
- 使用linq 搭配dbcontext 的local load方法,把数据从数据库调到内存中再进行处理。减轻数据库查询方面是蛮好的,但是记住把所有的数据都加载到内存中是一个昂贵的操作,如果你运行多个查询而仅仅是返回你数据的子集,你可以仅仅把你需要的数据加载到内存中,而不是把所有数据。
{ using (var context = new BreakAwayContext()) { context.Destinations.Load(); var sortedDestinations = from d in context.Destinations.Local orderby d.Name select d; Console.WriteLine("All Destinations:"); foreach (var destination in sortedDestinations) { Console.WriteLine(destination.Name); } var aussieDestinations = from d in context.Destinations.Local where d.Country == "Australia" select d; Console.WriteLine(); Console.WriteLine("Australian Destinations:"); foreach (var destination in aussieDestinations) { Console.WriteLine(destination.Name); } }
数据库优先的简单实战-schoolManagement
- 上午用mvc模式吧schoolmangemnet里的班级表循环输出了一下,文件结构是:
- 用数据库优先生成了schoolManagement的edmx文件;
- 在DAL层建立了schoolManagementDAL.cs,里面就一个getClasses()函数return一个list,函数里面通过使用schoolManagementEntity来new一个数据库上下文db,再通过linq的query获取一个class集合;
public class schoolMangementDAL:DbContext { public List<@class> GetClasses() { schoolManagementEntities db = new schoolManagementEntities(); var query = from d in db.classes select d; return query.ToList(); } }
- BSL层里有SchoolManagementBSL.cs,因为本实验没有对class做更多的处理,所以BSL层也只是new了一个schoolManagementDAL,调用了getclasses(),以便后续controller从BSL取数据;
public class SchoolMangeBSL { public static List<@class> test() { schoolMangementDAL smDAL = new schoolMangementDAL(); List<@class> classes = smDAL.GetClasses(); return classes; } }
- ViewModel层,新建了一个classesViewModel.cs,就一个属性List<@class>;
public class classesViewModel { public List<@class> classes { get; set; } }
- controller中把从BSL获取的list赋给classesViewModel,再return View(“classes”,classesViewModel);
public ActionResult Index() { List<@class> classes = SchoolMangeBSL.test(); classesViewModel cVD = new classesViewModel(); cVD.classes = classes; return View("classes",cVD); }
- View中注意@using 以及@model的写法 所以直接@foreach(@class c in @model.classes).这里不要混淆,@class是实体名称
@{ Layout = null; } @using WebApplication1.ViewModels @using WebApplication1.Models @model classesViewModel <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>classes</title> </head> <body> <div> hello<hr /> <table> <tr><td>id</td><td>name</td><td>teacherId</td></tr> @foreach(@class c in Model.classes) { <tr> <td>@c.id</td> <td>@c.name</td> <td>@c.teacherId</td> </tr> } </table> </div> </body> </html>
- 感觉里面的重点就是DAL层用EF获取数据库中数据的方法
- 最后其实有些疑问:为啥数据库优先生成的实体里是@class?;edmx里class的导航属性为啥会有一个class1,class2?
- 最后建个备忘吧,有关ef数据库优先的这部分,有一些资料是宋鑫给的在u盘里
试了一下linq var query = ...,试了一下dbcontext的查询
实验九
- 将访问employee的路径改为了Employee/index,当然要修改对应的controller和view的名字。
- controller中新增加addNew方法,view中增加CreateEmployee
- index上链到addNew的a标签的href写
有些特殊,在浏览器中把鼠标悬停到其上时显示http://localhost:1352/Employee/addNew<a href="/Employee/addNew">add employee</a>
c#中可以这么写
class A{
public string name{get;set;}
public string address{get;set;}
private int num;
public int Num{
get{
return num;
}
set{
num = value;
}
}
}
对于private成员,通过调用Num来实现安全访问