asp.net mvc5 step by step(二)——Data Annotations(data 注释)
以下使用在Entity Framework Code First
Entity Framework Code First 利用一种被称为约定(Conventions)优于配置(Configuration)的编程模式允许你使用自己的 domain classes 来表示 EF 所依赖的模型去执行查询、更改追踪、以及更新功能,这意味着你的 domain classes 必须遵循 EF 所使用的约定。然而,如果你的 domain classes 不能遵循 EF 所使用的约定,此时你就需要有能力去增加一些配置使得你的 classes 能够满足 EF 所需要的信息。
Code First 提供了两种方式来配置你的类:
- DataAnnotations, 使用简单属性;
- Fluent API, 以编程命令行式的方式来描述你的配置
本文将关注 DataAnnotations(位于命名空间 System.ComponentModel.DataAnnotations)
为了便于示例,我们先创建两个类:Blog 和 Post
以上类都是遵循约定的,但是你也可以使用 annotations 为 EF 提供更多的信息
Key主键
EF 依赖于每一个实体都有一个主键从而能够追踪实体。 在约定下,主键是通过寻找名称为 ID 或 ClassName + ID 的属性确定。那么如果类中没有此类的属性呢?我们把类改造如下(把 Id 改为 PrimaryTrackingKey)
此时如果我们添加 Scaffolded 会出现如下错误
我们需要使用 key annotation 确定哪一个属性是主键
我们使用 Code First's Database Generation 功能看看数据库的情况
Required非空
用于指示字段非空
运行看一下结果
我们在看一下后台数据库情况
MaxLength and MinLength长度限制
顾名思义,就是限制字段的长度
看一下后台数据库
运行看结果
NotMapped忽略
类中有些属性,如通过计算获得或其它列的合并而来的,我们并不希望其记录在数据库中,此时就可以使用 NotMapped Annotation
对于类也是一样的
ComplexType复杂类型
一般这种情况是不常见的:类中包含另一个类即一个完整的实体是由一系列类的集合来描述。例如我们在我们的模型中增加一个叫 BlogDetails 的类
注意 BlogDetails 不包含任何主键属性, 在领域驱动设计中被称为值对象,而在 EF 中则被称为复杂类型(ComplexType). Complex Types 是无法自我追踪的,但是我们可以通过 ComplexType Annotation 来改变这种尴尬
可以看到,在数据库中表 Blog 包含 BlogDetails 的所有两个属性,默认列名前缀为 complex type 即 BlogDetails
ConcurrencyCheck并发检查
ConcurrencyCheck Annotation 允许你可以在一个或多个属性上设置一个标记用于当用户更新或删除实体时做并发检查。
如果此时同时对此列进行更新,则会抛出异常 DbUpdateConcurrencyException
TimeStamp时间戳
通常用行版本号或时间戳来检查并发,除了使用 ConcurrencyCheck Annotation, 还可以使用更为精确的 TimsStamp, 前提是这个属性的类型是字节数组(byte array). Code First 在对待 TimsStamp 属性和 ConcurrencyCheck 属性是一样的,只不过能确保数据库中生成的字段是 non-nullable
在一个给定的类中只能有一个 TimsStamp 属性
看一下后台数据库
Table and Column表/列名
指定匹配到数据库的表/列名
可以看到表/列名已更改
DatabaseGenerated自增长
DatabaseGeneratedOption 有三个选项:
- DatabaseGeneratedOption.Computed: 在用 Code First 生成数据库的时候你可以在 byte 或 timestamp 列上使用 DatabaseGenerated Annotation,否则就应该在数据库存在的情况下使用因为如果数据库不存在,此时 Code First 不知道为计算列(Computed Column)选择使用什么样的公式
- DatabaseGeneratedOption.Identity: 如果主键为 integer 型,则数据库默认为自增长(效果等同于设置DatabaseGeneratedOption.Identity), 如果主键是 GUID 类型,则要显式设置自增长
- DatabaseGeneratedOption.None: 如果不想自增长,可设置成 DatabaseGeneratedOption.None
ForeignKey 外键
看看数据库
InverseProperty属性反转
InverseProperty 一般使用在当类间有多重关系的时候。
例如在 Post 中你可能不仅需要追踪谁写的也还要追踪有谁编辑了博客
此时你会看到后台数据库有四个外键 Person_Id, Person_Id1, CreatedBy_Id and UpdatedBy_Id
为了解决这个问题,我们可以使用 InverseProperty annotation 来明确属性间的指向
再一次看看数据库,情况已经发生了变化
以下用于验证数据
来自:https://msdn.microsoft.com/zh-cn/library/ee256141(VS.100).aspx
如何:使用 DataAnnotations 特性验证模型数据
本主题阐释了如何使用 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据模型中的各个字段的验证。 这些特性用于定义常见的验证模式,例如范围检查和必填字段。 System.ComponentModel.DataAnnotations 特性使 MVC 能够提供客户端和服务器验证检查,而无需您进行额外的编码。
System.ComponentModel.DataAnnotations 特性可用于实体数据模型 (EDM)、LINQ to SQL 和其他数据模型。 还可以创建自定义验证特性。 有关更多信息,请参见如何:使用自定义特性在数据模型中自定义数据字段验证。
与本主题对应的包含源代码的 Visual Studio 项目可从 Download(下载)网页获得。
下图显示了客户端验证失败时自动显示在浏览器中的错误消息。
使用 DataAnnotations 特性添加验证
向项目添加类以包含分部类定义。 有关更多信息,请参见如何:在数据模型中自定义数据字段验证。
向与正在使用的数据模型的命名空间匹配的分部类添加一个命名空间声明。
注意 在分部类中使用的不正确的命名空间会导致裸分部类,这是一种与任何其他类都不关联的分部类。 裸分部类是数据模型无法识别 DataAnnotations 特性的常见原因。 若要避免此问题,可以复制数据模型代码中的命名空间以确保您具有正确的命名空间。
命名分部类以匹配表示数据模型中的表的类声明,并将其粘贴到新的类文件中。
注意 类名称完全匹配是非常重要的。 确保分部类的名称匹配的最简单方法就是复制它。
下面的示例显示了 AdventureWorksLT_2008 示例数据库中的 Product 表的分部类。 在本示例中,由 MvcDA 命名空间表示数据库。
using System.ComponentModel.DataAnnotations;
namespace MvcDA {
[MetadataType(typeof(ProductMD))]
public partial class Product {
public class ProductMD {
[StringLength(50),Required]
public object Name { get; set; }
[StringLength(15)]
public object Color { get; set; }
[Range(0, 9999)]
public object Weight { get; set; }
// public object NoSuchProperty { get; set; }
}
}
}注意 类中包括名为 NoSuchProperty 的属性并已将其注释掉。 可以如本主题后面所述,将此属性用来测试分部类。
创建一个关联类(有时称为“合作者类”),该类包含表示表的分部类的属性。
关联类可以有任意名称,但习惯的做法在表类名称的后面追加“MD”或“MetaData”。 关联类必须用于 EDM 或 LINQ-to-SQL 模型,因为 CLR 类型不能用新的特性标记现有的属性。 如果直接使用 CLR 对象(有时称为“简单传统 CLR 对象 (POCO)”类型),则可以将特性直接应用于模型。
通过使用 MetadataTypeAttribute 特性将新类与表类关联。
在前面的示例中,以下代码行将新类与表类关联:
[MetadataType(typeof(ProductMD))]
将 System.ComponentModel.DataAnnotations 特性应用于属性。 可以将任意数量的特性应用于每个属性。
如果无法识别您应用的数据批注,则应验证是否可以在项目中识别分部类。 以下过程建议了一种测试类的方法。
测试分部类
将一个属性添加到分部类,其名称与相应的数据模型中的属性不匹配。
例如,取消对前一过程的示例中显示的 NoSuchProperty 属性的注释。
运行项目并输入要验证的数据。
如果可以识别分部类,则在进行验证时,将会引发 InvalidOperationException 异常并显示如下类似的消息:
类型“MvcDA.Product”的关联元数据类型包含下面的未知属性或字段:NoSuchProperty。 请确保这些成员的名称与主类型中的属性名称相匹配。
如果分部类为裸分部类,则不会引发异常。 在这种情况下,检查分部类名称以确保它与数据模型中相应的类名称匹配,并且使用了正确的命名空间。
删除在分部类中添加的用于测试的属性。
在添加服务器端验证后,可以通过包括必要的 JavaScript 验证文件和启用客户端验证来添加客户端验证。
添加客户端验证
向包含要验证的元素的视图添加对 JavaScript 验证文件的引用。 (常见做法是在 Site.master 文件中包括这些引用,使其应用于每个视图。)
下面的示例演示如何引用为了包括客户端验证所需要的 JavaScript 文件。 (在此示例中,引用了库的调试版本。)该示例还演示如何调用 EnableClientValidation 方法以便启用客户端验证。 启用客户端验证的常见方法是向 Site.master 文件中添加下面的代码。 但是,也可以将此代码添加到实现客户端验证的视图页面中。 如果在母版页中包括下面的代码,则每个视图将自动启用客户端验证。
<head runat="server">
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.debug.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.debug.js") %>" type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcValidation.debug.js") %>" type="text/javascript"></script>
<% Html.EnableClientValidation();%>
</head>
若要编译代码示例,需要以下组件:
Microsoft Visual Studio 2008 Service Pack 1 或 Visual Web Developer 2008 速成版 Service Pack 1。
AdventureWorksLT_2008 示例数据库。 有关如何下载和安装 SQL Server 示例数据库的信息,请参见 CodePlex 站点上的 Microsoft SQL Server Product Samples: Database(Microsoft SQL Server 产品示例:数据库)。 请确保针对所运行的 SQL Server 版本(Microsoft SQL Server 2005 或 Microsoft SQL Server 2008)安装了正确版本的示例数据库。
一个 MVC 应用程序,它具有从 AdventureWorksLT_2008 示例数据库创建的 EDM。 有关更多信息,请参见 ASP.NET 网站上的教程 Creating Model Classes with the Entity Framework(使用实体框架创建模型类)。
asp.net mvc5 step by step(二)——Data Annotations(data 注释)的更多相关文章
- ASP.NET MVC5 网站开发实践(二) Member区域–管理列表、回复及删除
本来想接着上次把这篇写完的,没想到后来工作的一些事落下了,放假了赶紧补上. 目录: ASP.NET MVC5 网站开发实践 - 概述 ASP.NET MVC5 网站开发实践(一) - 项目框架 ASP ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 修改及删除文章
上次做了显示文章列表,再实现修改和删除文章这部分内容就结束了,这次内容比较简单,由于做过了添加文章,修改文章非常类似,就是多了一个TryUpdateModel部分更新模型数据. 目录: ASP.N ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 添加文章
上次把架构做好了,这次做添加文章.添加文章涉及附件的上传管理及富文本编辑器的使用,早添加文章时一并实现. 要点: 富文本编辑器采用KindEditor.功能很强大,国人开发,LGPL开源,自己人的好东 ...
- ASP.NET MVC5 网站开发实践(二) Member区域–我的咨询列表及添加咨询
上次把咨询的架构搭好了,现在分两次来完成咨询:1.用户部分,2管理部分.这次实现用户部分,包含两个功能,查看我的咨询和进行咨询. 目录: ASP.NET MVC5 网站开发实践 - 概述 ASP.NE ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 咨询管理的架构
咨询.留言.投诉等功能是网站应具备的基本功能,可以加强管理员与用户的交流,在上次完成文章部分后,这次开始做Member区域的咨询功能(留言.投诉都是咨询).咨询跟文章非常相似,而且内容更少.更简单. ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 全部文章列表
显示文章列表分两块,管理员可以显示全部文章列表,一般用户只显示自己的文章列表.文章列表的显示采用easyui-datagrid.后台需要与之对应的action返回json类型数据 目录 ASP.N ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 文章管理架构
上次把member的用户部分完成,现在开始做文章管理部分.文章部分根据涉及显示现实文章列表,发布文章,修改文章,删除文章等功能.最终的实现目标是使用权限来控制用户是否能进行相应操作,管理员权限的会显示 ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(3)修改资料、修改密码
在上一篇博客中实现了用户的注销和登录,其实代码里落了点东西,就是用户登录要更新最后一次登录时间和登录IP,这次补上.今天做修改资料和修改密码,TryUpdateModel是新用到的东西. 目录: AS ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(2)用户登录、注销
上次实现了用户注册,这次来实现用户登录,用到IAuthenticationManager的SignOut.SignIn方法和基于声明的标识.最后修改用户注册代码实现注册成功后直接登录. 目录: ASP ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(1)用户注册
上一次把基本框架搭建起来了,这次开始整Web部分,终于可以看到界面了小激动一下.web项目部分从用户功能开始,基本有注册,登录.注销.查找.查看.删除等涉及Member区域和Manage区域. 目录: ...
随机推荐
- jquery解析XML在IE7下不兼容的问题
jquery在解析XML内容的时候在IE7下无法显示,是因为数据格式的问题,解决办法如下: $.ajax({ type:"POST", url:&quo ...
- 10.31NOIP模拟赛解题报告
心路历程 预计得分:\(100 +100 +80\) 实际得分:\(30 + 100 + 80\) 天天挂分..感觉我noip要凉.. T1不难,但是太坑了 T2不难 T3不难,但是在小机房考试脑子都 ...
- 基于svg.js实现对图形的拖拽、选择和编辑操作
本文主要记录如何使用 svg.js 实现对图形的拖拽,选择,图像渲染及各类形状的绘制操作. 1.关于SVG SVG 是可缩放的矢量图形,使用XML格式定义图像,可以生成对应的DOM节点,便于对单个图形 ...
- angular之$on、$emit、$broadcast
1.$scope.$on view事件 //View被加载但是DOM树构建之前时: $scope.$on('$viewContentLoading', function(event, viewConf ...
- 多盟、Testin云测、K9test,助阵阿里云1218 移动开发者狂欢
经过双十一.双十二全民剁手狂欢后,阿里巴巴旗下的云计算业务,也为IT程序员们打造一场独特的盛宴. 阿里云计算12月18日对旗下主力云计算产品进行打折促销,云服务商.风投机构等都将参与到这场狂欢中.“我 ...
- 批量删除微博的js代码
清空微博,网上找了一段js代码,试了下,还行. var fileref=document.createElement('script') fileref.setAttribute("type ...
- 系统变量 %USERPROFILE%
可以用CMD的SET命令来查看现有的系统变量,“="前的部分用%括起来就是. 常用: %USERPROFILE% =C:\Users\用户名 %SystemRoot% =C:\WINDO ...
- 柔性数组成员 (flexible array member)-C99-ZZ
学习flexible array member是因为阅读Redis源码遇到的,sds.h中一开始就用到了. ============================================== ...
- 「资料/转载」HTML标签英文单词对照表
<!--> / 注释 <!DOCTYPE> document type 文档类型 <a> anchor 超链接 <abbr> abbreviation ...
- 关于mysql启动问题---mysqld_safe mysqld from pid file * ended
#在[mysqld]中添加: datadir = /usr/local/mysql/data #添加 log-error = /usr/local/mysql/data/error.l ...