• 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数据注解。

  • 相关阅读:
    SubtextHTTP 模块
    asp.net控件设计时支持(2)自动格式设置
    新立得字体模糊解决经验
    详解新网银木马清除技巧
    Ubuntu 9.10 29日发布,更新列表已经公布
    小样儿想封我?WebOS 1.2.1再次突破iTunes同步限制
    检测到您尚未安装ALEXA工具条
    在Puppy Linux中安装Firefox
    一步一步教你用ES封装系统(最完整视频教程)
    C# 判断是否为数字
  • 原文地址:https://www.cnblogs.com/liuyuanhao/p/4471869.html
Copyright © 2020-2023  润新知