【c#】 MVC模式 ——《七天学会》系列学习心得

:此处关于c#语言特点另一篇转载的文章

    当前结构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),来获取数据集合

  1. BSL与DAL的区别是什么呢?我觉得最大得是DAL是直接与数据库打交道,通过linq获取相应的数据,当然linq可能写的胡里花哨但相对来说比较原始;而BSL负责接收DAL对应数据进一步处理。最好是直接返回ViewModel需要的数据,这样将会使controller更纯净
  2. 和ashx nvelocity进行对比,其实挺容易理解的,重点是把ViewModel之于View 类比为var data 之于渲染的那个页面。

    MVC

    return View("myView",employeeViewModel);
    

    ashx

    var data = {data = ....}
    String html = commonHelper.RenderHtml("test.html",data)



  3. 模板语法。默认是Razor 但是Nvelocity也能用,个人感觉Razor语法比nvelocity复杂,功能也应该全面一些
  4. 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 代码优先)
  1. 此次又添加了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);
            }
        }
  2. 所以相应的改动就发生在了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() ;
    
            }
            
        }
  3. 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>
  4. 感觉以上由Employee类来生成数据库表的方法并不常用。

插一个,《七天》系列并没有介绍数据库优先的相关内容,所以此处插一些从其他地方找来的关于数据库优先的内容


找到了一个数据库优先的相关文章在收藏里,主要讲的从数据库映射过来的阶段,下面贴一个用

ef(dbcontext)进行查询,有部分Linq 的文章一共分为三篇

第一篇:http://www.cnblogs.com/telon/p/4092869.html

  1. 使用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
  1. 上午用mvc模式吧schoolmangemnet里的班级表循环输出了一下,文件结构是:
  2. 用数据库优先生成了schoolManagement的edmx文件;
  3. 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();
            }
        }

  4. 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;
    
            }
            
            
        }

  5. ViewModel层,新建了一个classesViewModel.cs,就一个属性List<@class>;
    public class classesViewModel
        {
            public List<@class> classes { get; set; }
        }

  6. 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);
            }

  7. 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>
    

  8. 感觉里面的重点就是DAL层用EF获取数据库中数据的方法
  9. 最后其实有些疑问:为啥数据库优先生成的实体里是@class?;edmx里class的导航属性为啥会有一个class1,class2?
  10. 最后建个备忘吧,有关ef数据库优先的这部分,有一些资料是宋鑫给在u盘里




试了一下linq  var query = ...,试了一下dbcontext的查询


实验九
  1. 将访问employee的路径改为了Employee/index,当然要修改对应的controller和view的名字。
  2. controller中新增加addNew方法,view中增加CreateEmployee
  3. index上链到addNew的a标签的href写
    <a href="/Employee/addNew">add employee</a>
    有些特殊,在浏览器中把鼠标悬停到其上时显示http://localhost:1352/Employee/addNew



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来实现安全访问








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原型模式是一种创建型设计模式,其提供了一种复制已有对象的方法来生成新对象的能力,而不必通过实例化的方式来创建对象。原型模式是通过克隆(浅复制或深复制)已有对象来创建新对象的,从而可以避免对象创建时的复杂过程。 在C#中,可以通过实现ICloneable接口来实现原型模式。ICloneable接口定义了Clone方法,该方法用于复制当前对象并返回一个新对象。需要注意的是,Clone方法返回的是Object类型,需要进行强制类型转换才能得到复制后的对象。 以下是一个简单的示例代码: ```csharp public class Person : ICloneable { public string Name { get; set; } public int Age { get; set; } public object Clone() { return MemberwiseClone(); } } // 使用示例 var person1 = new Person { Name = "Tom", Age = 20 }; var person2 = (Person)person1.Clone(); person2.Name = "Jerry"; Console.WriteLine(person1.Name); // 输出 "Tom" Console.WriteLine(person2.Name); // 输出 "Jerry" ``` 在上面的示例代码中,实现了一个Person类,并实现了ICloneable接口中的Clone方法来实现原型模式。复制对象时,使用MemberwiseClone方法进行浅复制,即只复制值类型的字段和引用类型字段的引用,而不复制引用类型字段所引用的对象。在使用示例中,首先创建一个Person对象person1,然后通过Clone方法复制一个新的对象person2,修改person2的Name属性后,输出person1和person2的Name属性,可以看到person1的Name属性并没有改变,说明person2是一个全新的对象。 需要注意的是,如果要实现深复制,即复制引用类型字段所引用的对象,需要在Clone方法中手动将引用类型字段复制一份。另外,使用原型模式时,需要注意复制后的对象和原对象之间的关系,如果复制后的对象修改了原对象的状态,可能会对系统产生意想不到的影响。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值