MVC-05 Model(1)

    在开发应用程序的过程中,经常需要处理许多大大小小的数据,例如,SQL Server数据库存取、连接AD(Active Directory)数据库进行验证、调用外部Web Service取得数据等。除了访问数据外,也经常需要对数据做成格式验证、逻辑验证等等。

 一、Model的责任

    在ASP.NET MVC中,Model负责所有与“数据”有关的任务。所以,不管是Controller或是View,都会参考到Model里定义的所有数据类型,或是用到Model里定义的一些数据操作方法,例如,新增、删除、更改、查询等。

    在Model里的程序,由于“只能”跟数据域商业逻辑有关,所以就不负责处理所有与数据处理无关的事,或是用来控制网站的运行流程等,而是专注于如何有效率地提供数据访问机制、交易环境、数据格式验证、商业逻辑验证等工作。

    由于Model的独立性非常高,如果你在一个Visual Studio方案中,有多个要开发的项目,比如有时我们会将Model独立成一个项目,让Model项目共享于不同的项目之间。

二、开发Model的基本观念

    当采用ASP.NET MVC框架时,虽然在Model层的开发技术繁多,而且ASP.NET MVC也保留了许多弹性,让各个不同的数据访问技术都能跟ASP.NET MVC集成。不过,若要充分发挥ASP.NET MVC快速开发的优势,还是建议读者在Model层采用ORM信息访问技术来开发,例如,LINQ to SQL、Entity Framework、NHibernate、Telerik OpenAccess ORM等。

1.何谓ORM

    ORM的全名是Object Relational Mapping,中文翻译为“对象关系映射”,是一种编程技术,用于实现面向对象程序语言里,不同类型系统之间的数据转换。通常在实务的应用上,大多数情况都会应用在数据库与面向对象程序自检的类型转换,例如,SQL Server中的关系型数据与.NET类型对象之间的转换等。

    换句话说,ORM是将结构化的关系型数据,映射成面向对象模型。如果以Entity Framework来说,就是试图将关系数据库的各种数据转换成.NET原生对象,或是将.NET模型类对象数据转换成关系型数据。

    使用ORM开发技术跟常规使用ADO.NET开发技术最大的差异,就在于操作“数据”的方便性与弹性。以往在使用ADO.NET开发数据访问程序时,开发人员通常必须先了解完整的数据库操作方法,才能顺利地从数据库取得数据,或是将对象的数据保存到数据库中。例如,要编写操作SQL Server数据库中的数据,就必须先学习T-SQL的使用方式;若要操作Oracle数据库中的数据,也必须先学习Oracle的SQL查询语法。学会之后还要学习各式ADO.NET的标准API,才能知道如何正确地与数据库交互,明白是要进行查询数据、更新数据、新增数据还是删除数据等。不同的数据库,在设计逻辑与SQL语法上都会有些小差异,而导致开发数据访问的程序代码缺乏效率。如此一来,也有违“关注点分离”的特性,若是套用“关注点分离”特性,照理说在开发.NET应用程序时,应该专注在对象的操作上,而非数据库数据的处理,当采用ORM开发技术后,便可以帮助我们达到这个目的。

    Entity Framwork是建构在ADO.NET数据提供者模型之上,也就是说,只要.NET运行环境能够使用ADO.NET连接数据库,Enity Framework便能顺利支持,在.NET运行环境下默认已经支持SQL Server 2005以上版本,如果要支持其他如Oracle、MySQL、SQLite、PostgreSQL等各式各样的关系数据库基本上也是没问题的,只要操作出相对应的Entity Framework数据提供者即可。

2.数据库开发模式

    采用Entity Framework或其他ORM开发极速,有时还可区分三种不同的开发模式,分别是数据库优先开发模式(Database First Development)、模型优先开发模式(Model First Development)、程序代码优先开发模式(Code First Development)。

(1)数据库优先开发模式

    顾名思义,数据库优先开发模式就是针对数据库进行设计,以数据库里定义的数据结构(Schema)为主。当应用程序在卡法的时候,必须依据数据库的结构设计来进行开发,使用的ORM框架必须能够依据数据库结构设计生成相应的对象模型,才能提供给应用程序来使用。

(2)模型优先开发模式

    模型优先开发模式是指在ORM架构中创建对象模型,让应用程序能够依据这些对象模型进行开发。需要实际访问数据库时,只要通过Entity Framework数据提供者的协助,动态生成相应的SQL语法,即可创建出完整的数据库。

    一般来说,支持模型优先开发模式的ORM框架,都会有相对应的程序代码生成技术,在模型被创建的同时自动生成相对应的程序代码。以Entity Framework为例,在搭配Visual Studio的帮助下,即可通过Entity Framework设计工具,帮你创建对象模型,只要保存后,就会自动生成相关程序代码。

(3)程序代码优先开发模式

    程序代码优先开发模式是一种非常新颖的开发模式,也就是让开发人员直接依据需求,编写类别与属性(程序代码),而这些撰写的类别与属性正是定义出应用程序所需的数据模型,并且通过ORM框架的管理,便可让这些POCO类型,转换成实体模型(Entity Model)。

    直到程序开始运行后,通过ORM框架,就可以自动依据这些类别,定义创建数据库、表格、字段与其他数据结构(Schema)。这样开发人员便可以完全不需要接触数据库这一端的各种管理工作(如创建表格字段、设计数据表、设计数据表关联等),也不用学习各式数据库的使用差异(如SQL Server、Oracle、MySQL、SQLite等),省去这些工作之后,开发人员更能专注在应用程序的需求开发,而不会因为不熟悉数据库操作而束手束脚。

三、LocalDB介绍

    微软最新推出的SQL Server 2012 Express LocalDB,是一种SQL Server Express的运行模式,特别适合在开发环境使用,也内建在Visual Studio 2012之中。

1.LocalDB的运作方式

    在安装好SQL Server 2012 Express LocalDB之后,默认会有个实例名,为v11.0。

2.如何连接LocalDB实例

(1)使用Management Studio连接LocalDB

    在连接对话框中输入正确服务器名称,(localdb)\v11.0。只有新版的SQL Server 2012 Management Studio才能识别这组新的服务器名称。

(2)通过.NET程序连接LocalDB实例

    连接字符串如下。

Server=(LocalDB)\v11.0; Integrated Security=true; AttachDbFileName=D:\Data\MyDB1.mdf

3.管理LocalDB自动实例

4.管理LocalDB具名实例

四、使用Code First创建数据模型

    ASP.NET MVC4与当前最新版的Entity Framework 5同时上市,尤其强化了程序代码优先开发模式的支持。

1.创建数据模型

(1)声明主键

    要想在Entity Framework声明主键,最简单的方式就是不要声明,直接把属性名称设置为Id或是类名+“Id”也可以,并将该属性指派为int类型即可。EF Code First会自动识别出这个字段就是表格里的主键,并且会加上自动编号的识别规格设置。

     当希望使用其他域名当作主键时,就可能遇到一些麻烦。可以加上key属性(Attriute),引用System.ComponentModel.DataAnnotations命名空间。

using System;
using System.ComponentModel.DataAnnotations;namespace MvcGuestbook.Models
{public class Guestbook{[Key]public int No { get; set; }public string Name { get; set; }}
}

(2)声明必填字段

    声明为string的属性,在数据库表格里的字段设置为NOT NULL。如果需要改为必填字段,可以加上Required属性,引用System.ComponentModel.DataAnnotations命名空间。

using System;
using System.ComponentModel.DataAnnotations;namespace MvcGuestbook.Models
{public class Guestbook{[Key]public int No { get; set; }[Required]public string Name { get; set; }}
}

(3)声明允许NULL字段

    声明为DateTime的属性,在数据库表格里的字段设置为NOT NULL。如果需要改变允许为空字段,可以加上一个问号,不需要引用任何命名空间。

using System;
using System.ComponentModel.DataAnnotations;namespace MvcGuestbook.Models
{public class Guestbook{[Key]public int No { get; set; }[Required]public string Name { get; set; }public string Emai { get; set; }[Required]public string Message { get; set; }public DateTime? CreatedOn { get; set; }}
}

(4)声明字段长度

    我们也经常会在数据库中限定特定字段的字符串长度,以方便日后创建字段索引,可以使用MaxLength属性,引用System.ComponentModel.DataAnnotations。

using System;
using System.ComponentModel.DataAnnotations;namespace MvcGuestbook.Models
{public class Guestbook{[Key]public int No { get; set; }[Required][MaxLength(5)]public string Name { get; set; }[MaxLength(200)]public string Emai { get; set; }[Required]public string Message { get; set; }public DateTime? CreatedOn { get; set; }}
}

    也可以设置StringLength属性来限定字段长度。

Model类中为属性添加MaxLength说明,需要引用(    )命名空间。

A.System.Linq                             B. System.ComponentModel

C. System.ComponentModel.DataAnnotations  D. System.Collection.Generic

(5)声明字段默认值

(6)声明特定属性不是数据库中的字段

    只要数据模型中出现公开属性,默认就会在数据库中创建一个对应的字段,但如果在数据模型中的属性,是一个动态计算的属性,我们并不想在数据库中新增对应的字段时,该怎么办?可以加上NotMapped属性(Attribute),引用System.ComponentModel.DataAnotations.Schema。

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace MvcGuestbook.Models
{public class Guestbook{[Key]public int No { get; set; }[Required][MaxLength(5)]public string Name { get; set; }[MaxLength(200)]public string Emai { get; set; }[Required]public string Message { get; set; }[DatabaseGenerated(DatabaseGeneratedOption.Computed)]public DateTime? CreatedOn { get; set; }[NotMapped]public string FamilyName{get{return this.Name.Substring(0, 1);}set{this.Name = value.Substring(0, 1) + this.Name.Substring(1);}}}
}

 

使用EF Code First在模型中声明特定属性不是数据库中的字段,应使用(  )关键字。

A.Key    B.Required    C.DisplayName    D.NotMapped

(7)DisplayFormat

获取数据字段的显示格式。例如可用于设置日期的格式。

(8)DataType

获取与数据字段关联的类型。例如DataType.Date。

(9)DatabaseGeneratedOption

DatabaeGeneratedOption.Computed,计算列

DatabaseGeneratedOption.Identity,标识自动加1

DatabaseGeneratedOption.None,没有标识,不自动加1

(10)Column

将类与数据库中的表相关。 [Column(“FirstName”)]public string FirstMidName{get;set;}

2.创建数据上下文类

    数据上下文类,在Entity Framework Code First开发模式下非常重要,主要用来追踪与识别对象的变更追踪。少了这个类别,Entity Framework就完全无法运作。

    自动添加数据上下文类,可以在添加控制器时操作。

    public class MvcGuestbookContext : DbContext{public MvcGuestbookContext(): base("name=DefaultConnection"){}public DbSet<Guestbook> Guestbooks { get; set; }}

    构造函数中的DefaultConnection为连接字符串的名字,这个连接字符串必须存储在web.config中。DbSet<Guest>类型的Guestbooks变量,代表的是Guestbook这个类型的数据库集合对象。

    如果希望将Guestbook数据模型被声明成只读,不让应用程序对其写入任何数据,那么可以修改数据上下文类,让DbSet集合属性只提供get实体。

    public class MvcGuestbookContext : DbContext{public MvcGuestbookContext(): base("name=DefaultConnection"){}public DbSet<Guestbook> Guestbooks{get { return Set<Guestbook>(); }}}

 

3.设计模型之间的关联性

    在设计数据库结构时,当遇到表格与表格间有关联存在时,一般会通过创建外键(Foreign Key)的方式设计表格之间的关联关系。

(1)设计模型之间的一对多关联

public class Guestbook{[Key]public int No { get; set; }[Required][MaxLength(5)]public string Name { get; set; }[MaxLength(200)]public string Emai { get; set; }[Required]public string Message { get; set; }public virtual Member Member { get; set; }}
    public class Member{public int Id { get; set; }[Required][MaxLength(5)]public string Username { get; set; }[MaxLength(10)]public string Password { get; set; }public DateTime? LastLoginTime { get; set; }

public virtual ICollection<Guestbook> Guestbooks { get; set; }}

 (2)设计模型之间的多对多关联

    将上述代码中的public virtual Member Member { get; set;},更改为:

public virtual ICollection<Member> Members { get; set; }

4.启用延迟装入特性

    使用ORM框架,基本上都会添加“延迟装入”的特性支持,Entity Framework当然也不例外。当使用Entit Framework的ObjectContext与DbContext操作数据时,默认都启用“延迟装入”。也就是当我们在应用程序里通过LINQ to Entity查询数据时,如果遇到关联数据尚未装入的情况,Entity Framework会自动帮我们再向数据库索取关联数据,全自动地取得关联数据,大幅降低编写访问关联数据的程序代码。

    若要在Code First模型类别中启用“延迟装入”特性,必须在属性声明时加上virtual关键词。

    >>导航属性?

    它是实体类上的可选属性,它允许从关联的一端导航到另一端。与其他属性不同,导航属性并不携带数据。

转载于:https://www.cnblogs.com/meetyy/p/3474092.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机 数据库知识点,数据库知识点总结

实体&#xff0d;联系模型基本概念实体和属性实体是客观存在并且可以相互区分的任何事物属性是实体所代表事物具有的某种特性每个属性都有一定的取值范围&#xff0c;成为该属性的值域实体集和码实体集是具有相同属性的实体的集合实体的值是该实体诸属性值的列表实体集的值是该…

计算机网络课程思政教学设计,信息与网络工程学院成功举办第一届课程思政教学设计大赛...

为有效贯彻全国高校思想政治工作会议精神&#xff0c;强化课程思政建设&#xff0c;全面提高人才培养质量&#xff0c;根据《教务处关于举办第一届课程思政教学设计大赛的通知》要求&#xff0c;结合学院工作安排&#xff0c;7月18日&#xff0c;信息与网络工程学院在龙湖校区西…

Java 中参数传递是传值还是引用?

2019独角兽企业重金招聘Python工程师标准>>> 明确概念 值传递&#xff1a;指的是将变量的一个备份传过去&#xff0c;当该备份被修改后&#xff0c;不会影响原来变量的值&#xff1b; 引用传递&#xff1a;指的是将该变量的地址传过去&#xff0c;当值修改后&#x…

sencha touch 手势识别左右滑动

sencha touch 中添加手势识别非常简单&#xff0c;就是监听 dom 元素的 move 事件&#xff1a; 1. 为你的 view 注册 swipe 事件 // 为当前 view 注册手势滑动事件 Ext.get(myTouchView).on(swipe, onViewSwipe, this); 2. 判断滑动方向 // 手势滑动监听事件 onViewSwipe : fun…

比较两浮点数的方法

在工作中&#xff0c;我需要比较一系列数据&#xff0c;一方数据精度为两位小数,而另一方精度为三位小数。我需要将三位小数四舍五入成两为小数后进行比较。在操作的过程中&#xff0c;问题出现了&#xff0c;明明应该相等的数据却走了不等的分支。什么原因导致呢&#xff1f;一…

IIS8托管WCF服务

WCF服务程序本身不能运行&#xff0c;需要通过其他的宿主程序进行托管才能调用WCF服务功能&#xff0c;常见的宿主程序有IIS&#xff0c;WAS&#xff0c;Windows服务&#xff0c;当然在学习WCF技术的时候一般使用控制台应用程序或WinForm程序进行托管。本文将详细介绍如何使用I…

北京师范大学认知神经科学 计算机,北京师范大学认知神经科学和学习国家重点实验室.pdf...

北京师范大学认知神经科学和学习国家重点实验室北京师范大学认知神经科学与学习国家重点实验室DTI 、静息fMRI、形态学测量原理及数据分析与应用深度讲习班(第二轮通知)近年来&#xff0c;磁共振技术已广泛地应用到神经科学、认知神经科学、临床医学等领域的研究&#xff0c;而…

JAVA面向对象-----instanceof 关键字

instanceof 关键字 1&#xff1a;快速演示instanceof Person pnew Person();System.out.println( p instanceof Person); 2&#xff1a;instanceof是什么&#xff1f; 1&#xff1a;属于比较运算符&#xff1a; 2&#xff1a;instanceof关键字&#xff1a;该关键字用来判断一…

电子工程师必去的论坛网站

Abstract 搞电子不能闭门造车&#xff0c;要到网上去交流交流&#xff0c;做个网络吸血鬼也好。本人偶然也发一些资料&#xff0c;还是要感谢活跃在各大论坛上的大虾们&#xff0c;让小弟要走了不少弯路。有问题google一下&#xff08;不是本人崇洋媚外&#xff0c;google的功能…

对象的引用

int、datetime、bool、char等类型都属于值类型&#xff08;valuetype&#xff09;&#xff0c;赋值的时候是传递拷贝。 普通的对象则是引用类型&#xff0c;赋值的时候是传递引用。传递给函数也是引用传递的。转载于:https://www.cnblogs.com/roboot/archive/2012/02/15/235329…

Cesium应用篇:3控件(3)SelectionIndicator InfoBox

假设这样一个场景&#xff0c;用户在Cesium球上加载了一个GeoJson文件&#xff08;DataSource&#xff09;&#xff0c;里面是全美国所有州的Geometry信息&#xff08;Entity&#xff09;&#xff0c;叠加到球面后&#xff0c;你自然会有一种冲动&#xff0c;点击某一个州&…

北理工计算机学院新闻,北理工计算机学子勇夺CVPR 2021 AI安全国际顶级赛事季军...

2021年4月19日&#xff0c;CVPR 2021挑战者计划第六期落下帷幕。由北理工计算机学院教师李元章、张全新及广州大学李进教授指导的DemiguiseWoo战队&#xff0c;在挑战赛赛道二“ImageNet无限制对抗攻击”发起冲击&#xff0c;最终以9303.6的总分取得决赛第三名的好成绩&#xf…

字符串入门

暴力 字典树总结&#xff1a;字典树的功能就是map字符串得到编码或者查询前缀关系套模板的时候注意t,s,&#xff0d;‘a’,[26],sz0的初始化还有一个问题&#xff0c;到底字典树开多少内存比较合适&#xff0c;反正至少是要开字符总长度*2hdu1251 http://acm.hdu.edu.cn/showpr…

C++ 的基础概念(3)——多态详解。

最近两次面试都问到了多态&#xff0c;我也不得不重视起来了&#xff0c;最近最大的收获就是&#xff1a;基础知识很重要&#xff0c;就算你很会写代码&#xff0c;但是面试官问你基础知识答不上来的话&#xff0c;也很难被人赏识和录用&#xff0c;所以还是要多补补基础概念&a…

美育在计算机教育中应用,在现代教育技术中绽放数学美育之花

21世纪是信息化的社会&#xff0c;计算机、网络等现代技术的飞速发展&#xff0c;作为现代教育技术&#xff0c;计算机多媒体技术和网络技术已经越来越多地走进小学数学课堂&#xff0c;为深化教学改革&#xff0c;培养学生能力&#xff0c;发展学生个性&#xff0c;提供了崭新…

.NET Forms身份验证

.NET表单身份验证 ASP.NET Forms 身份验证的简单实现&#xff1a;1&#xff09;在Web.config文件中配置应用程序使用 Forms 身份验证&#xff1b;2&#xff09;创建登陆页面&#xff0c;将用户身份验证票证添加到Cookie集合。1.配置文件中设置为Forms验证<authentication mo…

Oracle SQL篇(三)Oracle ROWNUM 与TOP N分析

首先我们来看一下ROWNUM&#xff1a;含义解释&#xff1a;1、rownum是oracle为从查询返回的行的编号&#xff0c;返回的第一行分配的是1&#xff0c;第二行是2&#xff0c;依此类推。这是一个伪列&#xff0c;可以用于限制查询返回的总行数。2、rownum不能以任何基表的名称作为…

C++ Primer 第10章 pair类型

//10.2.cpp //至少使用三种方法创建pair对象。 //编写三个版本的程序&#xff0c;分别采用不同的方法来创建pair对象 //方法1&#xff1a;在定义pair对象时提供初始化式来创建pair对象#include<iostream> #include<vector> #include<utility> #include<st…

计算机对口升学可以报考的学校,对口升学可以报考的学校都在这里,赶快来收藏吧...

对口升学指对口高考&#xff0c;在平常又叫对口单招&#xff0c;对口升学&#xff0c;是从中等职业学校毕业生招生&#xff0c;强调中等职业学校毕业生对口升高职的专业技能考试&#xff0c;以专业技能成绩为主要录取依据的招生办法。报名条件具有正式学籍的中等职业学校毕业生…

Visual Studio 常用快捷键 (二)

想不到上一篇 【Visual Studio 常用快捷键】 受这么多人的欢迎。看来大家对Visual Studio的用法非常感兴趣。 接下来我准备写一个 “Visual Studio使用技巧 ” 一个系列的博客。 希望对大家有所帮助 本篇继续介绍几个常用的快捷键 阅读目录 按两下Tab键回退到光标的上一次位置…