3.EF 6.0 Code-First实现增删查改

2018-06-22 06:03:19来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-entity-framework-5-0-code-first-approa/

或者:http://www.codeproject.com/Articles/640302/CRUD-Operations-Using-Entity-Framework-Code-Fi

系列目录:

 

  • Relationship in Entity Framework Using Code First Approach With Fluent API【【使用EF Code-First方式和Fluent API来探讨EF中的关系】】
  • Code First Migrations with Entity Framework【使用EF 做数据库迁移】
  • CRUD Operations Using Entity Framework 5.0 Code First Approach in MVC【在MVC中使用EF 5.0做增删查改】
  • CRUD Operations Using the Repository Pattern in MVC【在MVC中使用仓储模式,来做增删查改】
  • CRUD Operations Using the Generic Repository Pattern and Unit of Work in MVC【在MVC中使用泛型仓储模式和工作单元来做增删查改】
  • CRUD Operations Using the Generic Repository Pattern and Dependency Injection in MVC【在MVC中使用泛型仓储模式和依赖注入,来做增删查改】

 

本来不想写这篇的,因为感觉增删查改,实在是太Easy了。好了,为了巩固学习,还是继续吧:

打算实现书籍的增删查改,有两个实体,一个是Book【书籍实体】,另外一个是出版商实体【Publisher】,一个出版商可以出版很多书籍,一本书只能是由一个出版商出版。所以,书籍和出版商之间是一对多的关系。

先来看看整个项目的结构吧:

 

Entity实体中:

BaseEntity实体:【日期使用了数据注解,这样在显示的时候,就有格式了。】

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF.Entity
{
   public abstract class BaseEntity
    {

       /// <summary>
       /// ID
       /// </summary>
       public int ID { get; set; }

       /// <summary>
       /// 添加时间
       /// </summary>
       /// 
       [DataType(DataType.Date)]
       [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
       public DateTime AddedDate { get; set; }

       /// <summary>
       /// 修改时间
       /// </summary>
       /// 
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
       public DateTime ModifiedDate { get; set; }
    }
}

 

 Book实体:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF.Entity
{
    /// <summary>
    /// Book实体
    /// </summary>
    public class Book:BaseEntity
    {
        /// <summary>
        /// 书名
        /// </summary>
        public string BookName { get; set; }

        /// <summary>
        /// 书的作者
        /// </summary>
        public string BookAuthor { get; set; }

        /// <summary>
        /// 书的价格
        /// </summary>
        public decimal BookPrice { get; set; }

        /// <summary>
        /// 出版商编号
        /// </summary>
        public int PublisherId { get; set; }

        /// <summary>
        /// 导航属性---出版商
        /// </summary>
        public virtual Publisher Publisher { get; set; }
    }
}

 

出版商实体:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EF.Entity
{
   public class Publisher:BaseEntity
    {
       /// <summary>
       /// 出版商的名字
       /// </summary>
       public string PublisherName { get; set; }

       /// <summary>
       /// 导航属性
       /// </summary>
       public virtual ICollection<Book> Books { get; set; }
    }
}

 

然后在EF.Data项目中:

BookMap类:

using EF.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF.Data
{
    public class BookMap:EntityTypeConfiguration<Book>
    {
        public BookMap()
        {
            //配置主键
            this.HasKey(s => s.ID);
            //配置字段
            this.Property(s => s.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            this.Property(s => s.BookName).HasColumnType("nvarchar").HasMaxLength(50).IsRequired();
           // this.Property(s => s.BookAuthor).HasColumnType("nvarchar(50)").IsRequired();//注意这个和BookName字段配置的区别之处:这样写EF生成不了数据库
            this.Property(s => s.BookAuthor).HasColumnType("nvarchar").HasMaxLength(50).IsRequired();
            this.Property(s => s.BookPrice).IsRequired();
            this.Property(s => s.AddedDate).IsRequired();
            this.Property(s => s.ModifiedDate).IsRequired();
            this.Property(s => s.PublisherId).IsRequired();
          
            //配置关系[一个出版商可以出版很多书籍]【外键单独配置,不是必须在Property中配置,当然也可以在Property中配置】
            this.HasRequired(s => s.Publisher).WithMany(s => s.Books).HasForeignKey(s => s.PublisherId).WillCascadeOnDelete(true);

            //配置表名字
            this.ToTable("Books");
           

        }
    }
}

PublisherMap类:

using EF.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EF.Data
{
   public class PublisherMap:EntityTypeConfiguration<Publisher>
    {
       public PublisherMap()
       {
           //配置主键
           this.HasKey(s => s.ID);
           this.Property(s => s.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
          // this.Property(s => s.PublisherName).HasColumnType("nvarchar(50)").IsRequired();//这样写,有问题,生成不了数据库
           this.Property(s => s.PublisherName).HasColumnType("nvarchar").HasMaxLength(50).IsRequired();
           this.Property(s => s.AddedDate).IsRequired();
           this.Property(s => s.ModifiedDate).IsRequired();
          
       }
    }
}

 

出版商我这里不做增删查改,到时候手动添加几条数据进去,然后在Book的视图中,把出版商做成下拉框的样式:所以我这里额外添加一个实体:【PublisherModel实体中的构造函数里的初始化属性嗲吗,不能忘记!!!】

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EF.Web.Models
{
    public class PublisherModel
    {
        public PublisherModel()
        {
            PublisherList = new List<SelectListItem>();
        }

        [Display(Name="PublisherName")]
        public int PublisherID { get; set; }

        public List<SelectListItem> PublisherList { get; set; }
    }
}

 

数据上下文类:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace EF.Data
{
   public class EFDbContext:DbContext
    {
       public EFDbContext()
           : base("name=DbConnectionString")
       { 
       
       }

       protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {
           var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
        .Where(type => !String.IsNullOrEmpty(type.Namespace))
        .Where(type => type.BaseType != null && type.BaseType.IsGenericType
             && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
           foreach (var type in typesToRegister)
           {
               dynamic configurationInstance = Activator.CreateInstance(type);
               modelBuilder.Configurations.Add(configurationInstance);
           }  
           //base.OnModelCreating(modelBuilder);
       }
    }
}

Ef.Data项目和Web项目中都要加上连接字符串:

<connectionStrings>
    <add name="DbConnectionString" connectionString="Server=.;Database=EFCURDDB;uid=sa;Pwd=Password_1" providerName="System.Data.SqlClient"/>
  </connectionStrings>

 

现在看看Web项目:

using EF.Data;
using EF.Entity;
using EF.Web.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace EF.Web.Controllers
{
    public class BookController : Controller
    {
        private EFDbContext db;
        public BookController()
        {
            db = new EFDbContext();
        }
        #region 列表
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View(db.Set<Book>().ToList());
        }
        #endregion

        #region AddBook
        /// <summary>
        /// 添加Book
        /// </summary>
        /// <returns></returns>
        public ActionResult AddBook()
        {
            PublisherModel model = new PublisherModel();
            List<Publisher> listPublisher = db.Set<Publisher>().ToList();

            foreach (var item in listPublisher)
            {
                model.PublisherList.Add(new SelectListItem()
                {
                    Text = item.PublisherName,
                    Value = item.ID.ToString()

                });
            }

            ViewBag.PublishedList = model.PublisherList;


            return View();
        }

        /// <summary>
        /// 添加Book
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult AddBook([Bind(Include = "BookName,BookAuthor,BookPrice,AddedDate,ModifiedDate,PublisherId")] Book model)
        {
            Book addBook = new Book() {
            AddedDate=model.AddedDate,
            BookAuthor=model.BookAuthor,
            BookName=model.BookName,
            BookPrice=model.BookPrice,
            ModifiedDate=model.ModifiedDate,
            PublisherId = Convert.ToInt32( Request["PublishedName"].ToString())
                //这里因为出版商我用的是另外的Model,视图中使用模型绑定只能用一个Model,所以修改和添加只能这样搞了。
            
            };
            db.Entry(addBook).State = EntityState.Added;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        #endregion

        #region UpdateBook
        /// <summary>
        /// 修改Book
        /// </summary>
        /// <param name="bookId"></param>
        /// <returns></returns>
        public ActionResult UpdateBook(int bookId)
        {
            PublisherModel model = new PublisherModel();
            List<Publisher> listPublisher = db.Set<Publisher>().ToList();

            foreach (var item in listPublisher)
            {
                model.PublisherList.Add(new SelectListItem()
                {
                    Text = item.PublisherName,
                    Value = item.ID.ToString()

                });
            }

            ViewBag.PublishedList = model.PublisherList;



            Book bookModel = db.Set<Book>().Where(s => s.ID == bookId).FirstOrDefault();
            return View(bookModel);
        }

        /// <summary>
        /// 修改Book
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult UpdateBook([Bind(Include = "ID,BookName,BookAuthor,BookPrice,AddedDate,ModifiedDate,PublisherId")] Book model)  //注意这里一定别忘记绑定 ID列哦
        {
            Book bookModel = db.Set<Book>().Where(s => s.ID == model.ID).FirstOrDefault();
          
            if (bookModel != null)
            {
                Book updatemodel = new Book() {
                    AddedDate = model.AddedDate,
                    BookAuthor = model.BookAuthor,
                    ID = model.ID,
                    ModifiedDate = model.ModifiedDate,
                    BookName = model.BookName,
                    BookPrice = model.BookPrice,
                    PublisherId = Convert.ToInt32(Request["PublishedName"].ToString())//这里因为出版商我用的是另外的Model,视图中使用模型绑定只能用一个Model,所以修改和添加只能这样搞了。
                };
                db.Entry(bookModel).CurrentValues.SetValues(updatemodel);  //保存的另外一种方式
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            else
            {
                return View(model);
            }

            #region 保存的方式二
            //db.Entry(model).State = EntityState.Modified;
            //db.SaveChanges();
            //return RedirectToAction("Index"); 
            #endregion
        }
        #endregion

        #region DeleteBook
        public ActionResult DeleteBook(int bookId)
        {
            Book model = db.Set<Book>().Where(s => s.ID == bookId).FirstOrDefault();
            return View(model);
        }

        [HttpPost]
        public ActionResult DeleteBook(int bookId, FormCollection form)
        {
            Book model = db.Set<Book>().Where(s => s.ID == bookId).FirstOrDefault();
            db.Entry(model).State = EntityState.Deleted;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        #endregion

    }
}

 

视图代码,我使用MVC模板生成:【适当做修改】

AddBook视图:

@model EF.Entity.Book

@{
    ViewBag.Title = "AddBook";
}

<h2>AddBook</h2>


@using (Html.BeginForm("AddBook","Book",FormMethod.Post)) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Book</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.AddedDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.AddedDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.AddedDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ModifiedDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ModifiedDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ModifiedDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BookName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BookAuthor, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookAuthor, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookAuthor, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BookPrice, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookPrice, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookPrice, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PublisherId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("PublishedName", ViewData["PublishedList"] as List<SelectListItem>)
                @*@Html.EditorFor(model => model.PublisherId, new { htmlAttributes = new { @class = "form-control" } })*@
                @Html.ValidationMessageFor(model => model.PublisherId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

UpdateBook视图:

@model EF.Entity.Book

@{
    ViewBag.Title = "UpdateBook";
}

<h2>UpdateBook</h2>


@using (Html.BeginForm("UpdateBook","Book",FormMethod.Post))
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Book</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.AddedDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.AddedDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.AddedDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ModifiedDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ModifiedDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ModifiedDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BookName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BookAuthor, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookAuthor, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookAuthor, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BookPrice, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.BookPrice, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.BookPrice, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.PublisherId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("PublishedName", ViewData["PublishedList"] as List<SelectListItem>)
                @*@Html.EditorFor(model => model.PublisherId, new { htmlAttributes = new { @class = "form-control" } })*@
                @Html.ValidationMessageFor(model => model.PublisherId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

注意:这里我只是把有改动的视图贴了出来,其他的视图,根据MVC模板生成之后,就不用管了。

@model IEnumerable<EF.Entity.Book>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "AddBook")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.AddedDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ModifiedDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.BookName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.BookAuthor)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.BookPrice)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.PublisherId)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.AddedDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ModifiedDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.BookName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.BookAuthor)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.BookPrice)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.PublisherId)
        </td>
        <td>
            @Html.ActionLink("Edit", "UpdateBook", new { bookId = item.ID }) |
            @Html.ActionLink("Details", "DetailsBook", new { bookId = item.ID }) |
            @Html.ActionLink("Delete", "DeleteBook", new { bookId = item.ID })
        </td>
    </tr>
}

</table>

效果图:

 

 

 

 总结:1.下拉框实体中,构造函数初始化语句不能忘记。

2.修改的方式,有新变化看代码;

3.模型绑定的时候,特别要注意,Bind的字段,修改的时候,Bind字段ID不能少。

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:【开源分享:入门到精通ASP.NET MVC+EF6+Bootstrap】从这里开始

下一篇:ASP.NET MVC——URL路由