zoukankan      html  css  js  c++  java
  • EF CodeFirst增删改查之‘CRUD’

       最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来。

       十年河东十年河西,莫欺少年穷

       学无止境,精益求精

       本篇旨在学习EF增删改查四大操作

       上一节讲述了EF CodeFirst 创建数据库,本节继续引用上一节的相关类学习EF的CRUD操作

       废话少说,直接上要点,上一节中的模型类我作了如下修改:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    using System.Linq;
    using System.Web;
    
    namespace EF_Test.DAL
    {
        public class Student
        {
            [Key]
            public int Id { get; set; }
            [Required]
            [StringLength(10)]
            public string Name { get; set; }//姓名
            [StringLength(2)]
            public string Sex { get; set; }//性别
            [StringLength(20)]
            public string StudentNum { get; set; }//学号
        }
    
        public class Course
        {
            [Key]
            public int Id { get; set; }
            [Required]
            [StringLength(20)]
            public string Name { get; set; }//课程名称
        }
    
        public class Score
        {
            [Key]
            public int Id { get; set; }
    
            public int StudentScore { get; set; }//学生分数
    
            public int StudentID { get; set; }//学生ID
    
            public int CourseID { get; set; }//课程ID
    
            public virtual Student Student { get; set; }//virtual关键字修饰,用于延迟加载 提高性能 只有显式调用时  属性==对象
    
            public virtual Course Course { get; set; }//virtual关键字修饰,用于延迟加载 提高性能 只有显式调用时  属性==对象
        }
    
        public class StudentContext : DbContext
        {
            public StudentContext()
                : base("StudentContext")//指定连接字符串
            {
    
            }
            public DbSet<Student> Students { get; set; }
            public DbSet<Course> Courses { get; set; }
            public DbSet<Score> Scores { get; set; }
    
            /// <summary>
            /// OnModelCreating方法中的modelBuilder.Conventions.Remove语句禁止表名称正在多元化。如果你不这样做,所生成的表将命名为Students、Courses和Enrollments。相反,表名称将是Student、Course和Enrollment。开发商不同意关于表名称应该多数。本教程使用的是单数形式,但重要的一点是,您可以选择哪个你更喜欢通过包括或省略这行代码的形式。
            /// </summary>
            /// <param name="modelBuilder"></param>
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
        }
    }

       有了以上模型类,我们就可以创建一些测试数据了

       新建一个StudentInitializer类如下:

        public class StudentInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<StudentContext>
        {
            public void InitLoad(StudentContext context)
            {
                //添加学生
                var studentList = new List<Student>
               {
                    new Student{Name = "陈依依", Sex = "", StudentNum = "081309201"},
                    new Student{Name = "戚永景", Sex = "", StudentNum = "081309202"},
                    new Student{Name = "刘华丽", Sex = "", StudentNum = "081309203"},
                    new Student{Name = "薛正钦", Sex = "", StudentNum = "081309204"},
                    new Student{Name = "王松涛", Sex = "", StudentNum = "081309205"},
                    new Student{Name = "王自龙", Sex = "", StudentNum = "081309206"},
                    new Student{Name = "高其峰", Sex = "", StudentNum = "081309207"},
                    new Student{Name = "陈欣欣", Sex = "", StudentNum = "081309208"},
                    new Student{Name = "陈丽阳", Sex = "", StudentNum = "081309209"}
               };
                studentList.ForEach(s => context.Students.Add(s));
                context.SaveChanges();
                //添加课程
                var courseList = new List<Course>
                {
                    new Course{ Name="数据结构"},
                    new Course{ Name="计算机原理"},
                    new Course{ Name="网络技术"}
                };
                courseList.ForEach(s => context.Courses.Add(s));
                context.SaveChanges();
                //添加分数
                var scoreList = new List<Score>()
                {
                    new Score{ StudentID=1,CourseID=1,StudentScore=90},
                    new Score{ StudentID=2,CourseID=1,StudentScore=91},
                    new Score{ StudentID=3,CourseID=1,StudentScore=92},
                    new Score{ StudentID=4,CourseID=1,StudentScore=93},
                    new Score{ StudentID=5,CourseID=1,StudentScore=94},
                    new Score{ StudentID=6,CourseID=1,StudentScore=95},
                    new Score{ StudentID=7,CourseID=1,StudentScore=96},
                    new Score{ StudentID=8,CourseID=1,StudentScore=97},
                    new Score{ StudentID=9,CourseID=1,StudentScore=98}
                };
                scoreList.ForEach(s => context.Scores.Add(s));
                context.SaveChanges();
            }
        }

       根据上述类,我们就可以显式调用initLoad方法,创建一些测试数据,有了这些测试数据,我们就可以进行EF增删改查操作了。

       如果您还没能够成功创建数据库,请参考鄙人的上篇博客:EF CodeFirst 创建数据库,关于创建数据库的问题不作讲述。嘻嘻

       1、查询数据:

       1.1方法(循环加载并转化为List<T>):

            public ActionResult Index()//查询学生数据
            {
                List<Student> studentList = new List<Student>();
                foreach (var student in db.Students)
                {
                    studentList.Add(student);
                }
                return View(studentList);
            }

       1.2方法(LINQ 查询):

            public ActionResult Index()//查询学生数据
            {
                var StudentQuery = from b in db.Students select b;//IEnumerable 类型
                return View(StudentQuery);
            }

       1.3方法(将DbSet<T>转化为List<T>):

            public ActionResult Index()//查询学生数据
            {
                return View(db.Students.ToList());
            }

       1.4方法(原生态查询),在贴出代码之前,我们先认知下DbSet<T>类型

       

        由上图可知:DbSet<T>继承了IEnumerable类型,而我们知道LInq查询的初始结果就是IEnumerable类型,所以:我们直接返回DBSet<T>类型也是可以的,因此:有了如下查询:

            public ActionResult Index()//查询学生数据
            {
                return View(db.Students);
            }

       由上图可知:Add代表增加一个实体,Remove代表删除一个实体,Find代表根据主键查询一个实体,在此:我们对此三种方法不作解释,我们继续寻找查询方法:红色标注最后一个SqlQuery方法如何用呢?

       1.5方法(SqlQuery查询)

            public ActionResult Index()//查询学生数据
            {
                return View(db.Students.SqlQuery("select * from Student"));
            }

       1.6方法(IQueryable查询)注:根据上图,DbSet<T>也继承了这个东东,所以我们的查询结果也可以以这个东东为类型

            public ActionResult Index()//查询学生数据
            {
                using (StudentContext dv = new StudentContext())
                {
                    IQueryable<Student> query = dv.Students.Where(d => d.Name.Contains(""));
                   
                    return View(query);
                }
            }

       1.7方法(Find查询),上述截图我们看到Find(参数)方法,其实他是根据主键来进行查询的,这个方法也很简单,代码如下:

            /// <summary>
            /// Find 根据主键查询  返回学生学号
            /// </summary>
            /// <returns></returns>
            public string Index(int Id=1)
            {
                using (StudentContext dv = new StudentContext())
                {
                    return dv.Students.Find(Id).StudentNum;
                }
            }

       至此:EF查询的方法也就讲的差不多了,下面我们来研究下删除的用法,所谓删除就是Remove(Tentity entity)方法和RemoveRange(IEnumerable<TEntity> entities)方法

       2、删除数据:根据上述Remove方法

       2.1方法(删除一个实体)

            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public string Index4(int Id = 9)//删除Id为9的 陈丽阳 童鞋
            {
                using (StudentContext dv = new StudentContext())
                {
                    Student mol=dv.Students.Find(Id);
                    if (mol != null)
                    {
                        dv.Students.Remove(mol); dv.SaveChanges();
                        return "删除成功";
                    }
                    else
                    {
                        return "删除失败";
                    }
    
                }
            }

       2.2方法(删除实体集合) 上图中的:RemoveRange(IEnumerable<TEntity> entities)方法

            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public string Index4(int Id = 9)//删除姓王的童鞋
            {
                using (StudentContext dv = new StudentContext())
                {
                    var studentMol = db.Students.Where(d => d.Name.Contains(""));
                    if (studentMol != null)
                    {
                        dv.Students.RemoveRange(studentMol); 
                        dv.SaveChanges();
                        return "删除成功";
                    }
                    else
                    {
                        return "删除失败";
                    }
    
                }
            }

       到此:删除也就讲完了,下面我们继续增加的方法:

       3、增加(ADD方法和AddRange方法)

       咱们继续看上图哈,其实Add方法的参数类型和Remove方法的参数类型一样,AddRange方法的参数类型和RemoveRange方法的参数类型一样,有了删除的相关知识,想必增加的方法大家也都会写了

       3.1方法(Add方法)

            /// <summary>
            /// Add
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public string Index6()//
            {
                using (StudentContext dv = new StudentContext())
                {
                    Student mol = new Student()
                    {
                        Name="陈卧龙",
                        Sex="",
                        StudentNum="081309099"
                    };
                    dv.Students.Add(mol);
                    dv.SaveChanges();
                    return "OK";
                }
            }

       3.2方法(AddRange方法)

           /// <summary>
            /// AddRange
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public string Index6()//
            {
                using (StudentContext dv = new StudentContext())
                {
                    var studentList = new List<Student>
                    {
                    new Student{Name = "陈大龙", Sex = "", StudentNum = "081309211"},
                    new Student{Name = "陈小龙", Sex = "", StudentNum = "081309212"}
                    };
                    dv.Students.AddRange(studentList);
                    dv.SaveChanges();
                    return "OK";
                }
            }

       到此为止增加的方法也就被我们KO了,下面最后一个Update方法,一贯的概念,在更新之前,必须先找到这个对象,然后在更新这个对象

       4、Update方法:

            /// <summary>
            /// 更新
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public string Index5(int Id = 1)//将Id等于1的人 姓名由陈依依 改成 陈二二
            {
                using (StudentContext dv = new StudentContext())
                {
                    Student mol = dv.Students.Find(Id);
                    if (mol != null)
                    {
                        mol.Name = "陈二二";
                        dv.SaveChanges();
    
                        return "更新成功";
                    }
                    else
                    {
                        return "无值可更新";
                    }
                }
            }

       至此:EF 增删改查也就全部被我们KO了。

       我们都知道数据库连接执行相关操作后,我们要及时释放数据库资源,在此:参照MSDN上的方法:如下

            /// <summary>
            /// 释放数据库资源 断开连接
            /// </summary>
            /// <param name="disposing"></param>
            protected override void Dispose(bool disposing)
            {
                db.Dispose();
                base.Dispose(disposing);
            }

       最后,谢谢大家的耐心阅读,如果觉得还不错,就给个赞吧!谢谢!

       @陈卧龙的博客

  • 相关阅读:
    Java方法
    Java流程控制
    Java基础
    常用Dos命令
    MarkDown语法
    怎样获取最新版的javascript文件,解决被浏览器缓存的问题
    笔记:javascript操作iframe内的DOM元素,及调用iframe内的方法
    .net程序部署(mono方式)
    面向对象的一点简易理解
    [李说新语]系列(1)西汉勇士贯高到底该不该死
  • 原文地址:https://www.cnblogs.com/chenwolong/p/CRUD.html
Copyright © 2011-2022 走看看