标签:this 日期 success ons mat 表关联 说明 就是 names
原文:https://www.cnblogs.com/miro/p/4288184.html
基于前面的文章,本次我们更近一步,进行更加深入的讲解, 首先介绍下Attribute配置Data Model.
使用Attribute配置Data Model, 可以指定formatting, validation, database mapping rules
约定:下图中三种情况一般资料都翻译成"属性",为了区分,我们用下图中的表述方式。
接下来,我们先对常用的attribute进行举例说明。
首先打开ModelsàSysUser.cs
添加 public DateTime CreateDate { get; set; }
增加完之后及时使用Code First Migrations 方式更新数据库。(不然运行时会报contex和database不一致的错误)
注意把Migrations\ Configuration.cs中Seed方法中内容注释掉,因为
Code First Migrations 方式更新数据库详细做法参加上篇文章。
接着修改Views\Account\Index.cshtml,把创建日期显示出来,如下方框处。
大家注意到,默认情况下会显示出时间,我们只需要显示到日就可以了。
DataType 属性用来指定更加具体的数据类型,DataType枚举值提供了一些常见的类型,比如Date,Time,EmailAddress等。
但是DataType不能指定数据类型的显示格式,例如日期要什么格式显示。
这个时候就需要配合使用DisplayFormate属性来指定格式。
[DisplayFormat(DataFormatString="{0:yyyy-MM-dd}",ApplyFormatInEditMode=true)]
StringLength属性设置了数据库中存储字段的最大长度,为程序提供客户端和服务器端的验证。同样用这个属性也可以指定最小长度,不过不影响数据库的结构。
add-migration MaxLengthOnNames
update-database
Views\Account\Create.cshtml增加一个Helper:ValidationMessageFor用来显示验证信息
Controllers\AccountController.cs增加一个判断条件ModelState.IsValid,不然会出错。
有时会有这么一种情况,我们Model中的字段和数据库中表的字段要用不同的命名。例如我们Model中命名为UserName,数据库表中命名为LoginName.
打开数据库可以看到UserName已经变成LoginName了。
下面再列出其他常用的attribute, 就不举展开讲了,很容易可以看懂,大家可以自己尝试。
[StringLength(10,MinimumLength=1,ErrorMessage="名字在1和10个字之间")]
[Column("FirstName"),Display(Name = "First Name"),StringLength(50, MinimumLength=1)]
2.对某一些类型来说不需要使用Required, 例如DateTime, int,double,float,因为这些值类型不能被赋予空值,因此他们天生就具有Required的特性。
[Column(TypeName="money")]
public decimal Budget { get; set; }
指定Column的TypeName可以改变SQL data type,这个例子中就是知道使用SQL Server的money类型。
Column mapping一般来说不需要,因为EF通常会基于你为property定义的CLR类型选择合适的SQL Server data type.
The CLR decimal type maps to a SQL Server decimal type.
详细对应表:https://msdn.microsoft.com/en-us/library/bb896344.aspx
前面文章中我们介绍过显示关联表数据的方法。
第四篇文章介绍过通过navigation 属性显示关联表数据。
本篇文章就系统的讲解下多表关联数据显示的问题。
有三种方式EF可以加载关联数据到一个实体的navigation属性中,下面我就直接用MSDN上的截图来说明。
第一次读取entity的时候不会加载。
当需要读取navigation property的时候,相关的数据将会被自动读取。
这种情况会导致多次查询数据库。
当读取entity的时候,相关数据会被一起读取。
一般来说这种方式会产生一个join query来获取所有需要的数据。
通过Include方法来指定eager loading.
和lazy loading类似,除了需要在代码中明确指定需要获取的关联数据。
在读取navigation property时explicit loading 不会自动发生,你需要手动加载相关数据。
通过获取object state manager entry for entity,调用Collection.Load method for collections或者Reference.Load method for properties that hold a single entity.
一般来说,只有在关闭lazying loading的时候才会使用explicit loading
lazy loading 和 explicit loading都不立即获取property values,它们也被称作deferred loading.
Disable lazy loading before serialization
disable lazy loading的两种方式:
1.对特定的navigation properties来说,省略property的virtual关键字就可以了
2.对所有navigation properties来说, 在context类中,构造函数中设置LazyingLoadingEnabled 为false即可。
this.Configuration.LazyLoadingEnabled = false;
使用 code first migrations的方式更新下数据库。可以看到新的表结构已经生成了。
先看下原来的Views\Account\Index.cshtml
我们原来是显示SysUser主表内容,当点击Details时通过navigation property实现SysUseràSysUserRoleàSysRole多表间查询。
现在我们增加一列Department, 让这个表格能直接显示SysUser主表及相应的Department内容。
我们使用Eager Loading的方式将Department的内容也加载进去,打开Controllers\AccountController.cs, 在index修改一处地方:
运行,可以看到Department中的内容已经被我们加载进来了。
多对多关系可以拆解成一对多的关系,例如用户和角色(* to *)可拆解成:
为了演示这个场景,我们新建一个ViewModel,将需要显示的表都放进去。
因为前面的文章已经将基本的用法都讲过了,我这里就直接贴出代码以及最终的展示结果,如果有不理解的部分再给我留言。
Controllers\UserRoleController.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MVCDemo.ViewModels; using MVCDemo.DAL; using MVCDemo.Models; using System.Data.Entity; namespace MVCDemo.Controllers { public class UserRoleController : Controller { private AccountContext db = new AccountContext(); // // GET: /UserRole/ public ActionResult Index(int? id) { var viewModel = new UserRoleIndexData(); viewModel.SysUsers = db.SysUsers .Include(u => u.SysDepartment) .Include(u => u.SysUserRoles.Select(ur => ur.SysRole)) .OrderBy(u => u.UserName); if (id != null) { ViewBag.UserID = id.Value; viewModel.SysUserRoles = viewModel.SysUsers.Where(u => u.ID == id.Value).Single().SysUserRoles; viewModel.SysRoles = (viewModel.SysUserRoles.Where( ur => ur.SysUserID == id.Value)).Select(ur => ur.SysRole); } return View(viewModel); } } }
@model MVCDemo.ViewModels.UserRoleIndexData @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_LayoutAdmin.cshtml"; } <h2>UserRoles</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table table-striped"> <tr> <th> UserName </th> <th> Email </th> <th> CreateDate </th> <th> Department </th> <th> Roles </th> <th></th> </tr> @foreach (var item in Model.SysUsers) { string selectedRow = ""; if (item.ID==ViewBag.UserID) { selectedRow = "success"; } <tr class="@selectedRow"> <td> @Html.DisplayFor(modelItem => item.UserName) </td> <td> @Html.DisplayFor(modelItem => item.Email) </td> <td> @Html.DisplayFor(modelItem => item.CreateDate) </td> <td> @if (item.SysDepartment != null) { @item.SysDepartment.DepartmentName } </td> <td> @{ foreach (var userRole in item.SysUserRoles) { @userRole.SysRole.RoleName <br /> } } </td> <td> @Html.ActionLink("Select", "Index", new { id = item.ID }) </td> </tr> } </table> @if (Model.SysRoles != null) { <h3>Related Roles</h3> <table class="table table-striped"> <tr> <th>RoleName</th> <th>RoleDesc</th> </tr> @foreach (var item in Model.SysRoles) { <tr> <td> @item.RoleName </td> <td> @item.RoleDesc </td> </tr> } </table> }
[DisplayFormat(DataFormatString="{0:yyyy-MM-dd}",ApplyFormatInEditMode=true)]
[DisplayFormat(NullDisplayText = "No grade")]
[StringLength(10,MinimumLength=1,ErrorMessage="名字在1和10个字之间")]
标签:this 日期 success ons mat 表关联 说明 就是 names
原文地址:https://www.cnblogs.com/zhang1f/p/11118987.html