asp.net MVC Model 类的主键 int类型、string类型、GUID类型。
在使用asp.net mvc进行定义 模型类的时候,一般情况下,我们都会定义一个属性为 int iD{get;set;} 或为int ClassNameID {get;set;},在这种情况下
1、Int类型主键
EF的默认约定就是第一个属性如果是类名+id或是id(这两情况下id字母大小写没有关系),并且是int类型的,那么直接设置第一个属性为主键,同时设置自增长。不需要指定[Key]关键字(在 System.ComponentModel.DataAnnotations.Schema命名空间下面)
比如:
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public int Price { get; set; }
public DateTime Birthday { get; set; }
}
或为
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime Birthday { get; set; }
}
此时,如果用脚手架自动创建控制器和视图中,因id或classid已经被认为是主键了,属性在create,index视图中不会显示。
如果在字段加入了[DatabaseGenerated(DatabaseGeneratedOption.None)] 的数据注解,让你自己输入主键值而不是数据库自动创建它。
在新建和编辑视图中自动会将id字段显示出来,供用户输入 。
2、GUiD主键
模型:
public class Person
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //此数据注解并可表示可以在数据库中自动生成 GUID值,只是告诉基架 在操作方法中生成创建GUID值的代码。如person.PersonID = Guid.NewGuid();
public Guid PersonID { get; set; }
public string Name { get; set; }
public int Price { get; set; }
public DateTime Birthdaey { get; set; }
}
利用基架自动创建控制器和视图:
public ActionResult Create()
{
return View();
}
// POST: People/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "PersonID,Name,Price,Birthdaey")] Person person)
{
if (ModelState.IsValid)
{
person.PersonID = Guid.NewGuid(); //基架增加自动创建的代码,指定PersonID GUID属性值。
db.People.Add(person);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(person);
}
视图:基架生成的视图中已经没有了PersonID 的表单值,因为模型中已经注明 了有数据库自动创建。
using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
3、string类型主键,如果一个模型的属性名为ID或classNameID 它总被认为主键,在映射到数据库总是为主键值,也不需要Key数据注解。不管它的类型是int 还是string,还是GUID。如果是int型,被认为是自增长,自动生成的创建编辑视图不会显示此字段。如果是string类型,不会自增长,需要用户输入或指定,自动生成的创建编辑视图会显示此字段,提示用户输入。
第一种方式:给模型创建一个构造函数指定PersonID为GUID字符串,在Create 视图中,删除脚手架自动生成的PerosnID 表单字段值。在Creater的POST方法中模型绑定自动生成一个Person对象,它的PersonID=GUID的值。这是使用主键类型为string的最佳实践。
模型:
public class Person
{
public string PersonID { get; set; } //由于属性名 为classNameID ,因此被认为主键。但是它不会自增长。需要用户自行生成。
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime Birthday { get; set; }
public Person()
{
PersonID = Guid.NewGuid().ToString();
}
控制器:
// GET: People/Create
public ActionResult Create()
{
return View();
}
// POST: People/Create
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "PersonID,Name,Price,Birthday")] Person person)//是否绑定PersonID都不影响。
{
if (ModelState.IsValid) //模型绑定将自动创建一个Person对象,调用Person的构造函数生成GuiD 主键值。
{
db.People.Add(person);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(person);
}
视图:删除自动生成的PerserID表单字段。
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" }) //删除PersonID的表单字段,如果不删除,那么PersonID的值就会要求手动输入,不输入就会绑定到POST方法中的PersonID为空值,保存的数据库就会出错。
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
</div>
</div>
在Asp.net Identity 中默认使用的String 类型的主键值,也是相同的实现方法。只不过,我们在访问Applicationuser 的时候绑定用的大多数是ViewModel,而不是直接的ApplicationUser或基类IdentityUser 类。
查看到ApplicationUser class(和用户相关的类)继承了IdentityUser.cs (位于Microsoft.Asp.Net.Identity.EntityFramework.dll) 反编译后源码如下:
1 namespace Microsoft.AspNet.Identity.EntityFramework
2 {
3 using Microsoft.AspNet.Identity;
4 using System;
5
6 public class IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
7 {
8 public IdentityUser()
9 {
10 this.Id = Guid.NewGuid().ToString();
11 }
12
13 public IdentityUser(string userName) : this()
14 {
15 this.UserName = userName;
16 }
17 }
18 }
观察 IdentityUser.cs 它有继承了IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>这个泛型,所以我们也需要有对应的Int类型的 IdentityUserLogin, IdentityUserRole, IdentityUserClaim泛型类。
第二种方式:直接在控制器Crate POST方法中指定一个PersonID 值。
模型类保持不变,不使用构造函数
public class Person
{
public string PersonID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime Birthday { get; set; }
}
控制器:
Create 的Get方法保持与脚手架一致,不作改动。
POst方法去除对PersonID的绑定,(不去也无所谓。)
public ActionResult Create()
{
return View();
}
// POST: People/Create
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关
// 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Name,Price,Birthday")] Person person)
{
if (ModelState.IsValid)
{
person.PersonID = Guid.NewGuid().ToString(); //在POST方法中创建一个GUID值,转换成字符串,并赋值给PersonID属性。
db.People.Add(person);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(person);
}
视图中删去显示输入PersornID的表单字段。
第三种方式:在Create Get方法中创建一个空的对象,自动调用构造函数生成主键值,返给视图,然后提交表单,将ID值通过模型绑定再传给Create Post方法。这种方式相对于前两种方式暴露给了用户GUID的值了。
控制器:
模型
public class Person
{
public string PersonID { get; set; } //由于属性名 为classNameID ,因此被认为主键。但是它不会自增长。需要用户自行生成。
public string Name { get; set; }
public decimal Price { get; set; }
public DateTime Birthday { get; set; }
public Person()
{
PersonID = Guid.NewGuid().ToString();
}
public ActionResult Create()
{
Person person = new Person(); //可以在脚手架代码加入此项,调用 自定义的构造函数给 Create视图中的对象返回一个GUID值。
return View(person);
}
// POST: Desks/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = PersonID,Name,Price,Birthday")] Person person) //绑定表单传过来的personID值。
{
if (ModelState.IsValid)
{
db.People.Add(person);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(person);
}
}
Create视图代码:
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.PersonID, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PersonID, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PersonID, "", new { @class = "text-danger" })
</div>
</div>
为了不让主键字段在Create 视图中显示,可以使用@html.HiddenFor(model =>model.personID) 辅助方法代替上面的视图代码。
总结:在使用asp.net MVC codefirst进行开的时候,模型POCO类的主键可定义为int类型,GUID类型(避免主键值在各表中重复,String类型(由GUID值转换)。可以方便的利用基架自动生成 控制器的CRUD操作方法和相应的视图。
如果一个模型的属性名为ID或classNameID 它总被认为主键,在映射到数据库总是为主键值,也不需要Key数据注解。
asp.net MVC Model 类的主键 int类型、string类型、GUID类型。的更多相关文章
- ASP.NET MVC Model验证(三)
ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...
- ASP.NET MVC Model绑定(二)
ASP.NET MVC Model绑定(二) 前言 上篇对于Model绑定的简单演示想必大家对Model绑定的使用方式有一点的了解,那大家有没有想过Model绑定器是在什么时候执行的?又或是执行的过程 ...
- ASP.NET MVC Model元数据(五)
ASP.NET MVC Model元数据(五) 前言 在上一篇中我们描述了应用于Model上面的各种用于显示控制的特性类,在本篇中将详细的介绍这些特性类的应用,虽然它们跟Model元数据的直接关系并不 ...
- ASP.NET MVC Model验证(五)
ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...
- ASP.NET MVC Model验证(四)
ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...
- ASP.NET MVC Model验证(二)
ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...
- ASP.NET MVC Model验证(一)
ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...
- ASP.NET MVC Model绑定(六)
ASP.NET MVC Model绑定(六) 前言 前面的篇幅对于IValueProvider的使用做个基础的示例讲解,但是没并没有对 IValueProvider类型的实现做详细的介绍,然而MVC框 ...
- ASP.NET MVC Model绑定(五)
ASP.NET MVC Model绑定(五) 前言 前面的篇幅对于IValueProvider的获取位置和所处的生成过程做了讲解,本篇将会对IValueProvider的使用做个基础的示例讲解,读完本 ...
随机推荐
- mybatis查询返回null解决方案
mybatis查询返回null解决方案: 问题:查询出的列与javabean中的字段名不一致. 解决方案: 1.将javabean中的字段改为和查询出的列名一致: 2.将sql加入as改变列名,和ja ...
- 线程&线程池
线程 进程和线程: 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 注意:两个都是过程 线程一个特点: 一个进程中,多个线程共享资源 线程和进程区 ...
- HDU 5514 容斥原理
Frogs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submi ...
- Java面试题总结之数据库与SQL语句
1.有3 个表,表结构如下: Student 学生表(学号,姓名,性别,年龄,组织部门) Course 课程表(编号,课程名称) Sc 选课表(学号,课程编号,成绩). 1)写一个SQL 语句, ...
- 【转】C++函数的重载、覆盖和隐藏区别
网上看到的关于C++函数的重载.覆盖和隐藏区别的回答,如下(其内容来源于C++面试宝典中一道题目): a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:( ...
- PHPCMS中GET标签概述、 get 标签语法、get 标签创建工具、get 调用本系统演示样例、get 调用其它系统演示样例
一.get 标签概述 通俗来讲,get 标签是Phpcms定义的能直接调用数据库里面内容的简单化.友好化代码,她可调用本系统和外部数据,仅仅有你对SQL有一定的了解,她就是你的绝世好剑!也就是适合熟悉 ...
- 给工作赋予的新意义——Leo鉴书78
现代社会学三大奠基人有两位名字里有"马克思",他们都是德国人.当中一位就是写<资本论>的卡尔•马克思,另一位就是<新教伦理与资本主义精神>的作者马克思•韦伯 ...
- The sandbox is not sync with the Podfile.lock
github下载的Demo,很多时候使用到CocoaPods,有的时候因为依赖关系或者版本问题不能编译运行. 出现 以下错误 The sandbox is not sync with the Podf ...
- C#建立最简单的web服务,无需IIS
软件架构师何志丹 本程序仅仅是入门级程序.所以不考虑 1.多线程. 2,安全性. 3,不考虑端点下载文件. 4,Keep-Alive. 5,不考虑head. 6,为了简洁,删掉了catch的内容. e ...
- 【iOS开发】-NSString的扩展使用
第一:基本数据类型与字符串转换 //基本数据类型(int float,double char) 1)基本数据类型->NSString //1.int类型换换成字符串 int a = 88; NS ...