zoukankan      html  css  js  c++  java
  • Entity Framework(EF)(一)之database first

    1、EF简介
    ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案。
    该框架曾经为.NET Framework的一部分,但version 6之后从.NET Framework分离出来。

    EF是微软开发的一款ORM框架。ORM框架能够自动实现Entity实体的属性与关系型数据库字段的映射,增删改查的sql脚本由ORM来
    自动生成,使我们编码时不用考虑数据库数据结构,而是以操作实体对象的形式来完成与数据库的交互。
    与传统开发方式相比ORM可以使我们编写更少的代码来创建和维护应用程序。

    ef开发模式有多种:code first、database first。
    本文只是介绍database first,想要了解其他一些开发模式,请自行网上查找资料。

    2、database first
    “Database First”模式顾名思义:“数据库优先”,使用这种模式的前提是应用程序已经拥有相应的数据库,
    咱们可以使用EF设计工具由数据库生成数据模型类。

    3、操作准备
    (1)、本示例的开发环境是vs2012sqlservel 2012
               当然选择别的开发环境、数据库同样也是可以的。
    (2)、创建数据库、数据表
                第一、打开sqlserver数据库,新建一个数据库(database)并命名为:SchoolDB
                第二、创建数据表:T_Class
                               USE SchoolDB
                                 GO
                                CREATE TABLE T_Class(
                                         ID int primary key  IDENTITY(1,1) NOT NULL,
                                         Name nvarchar(max) NOT NULL
                                    )
                 第三、创建数据表:T_Student
                            USE SchoolDB
                            GO
                             CREATE TABLE T_Student(
                             ID int primary key identity(1,1) NOT NULL,
                             Name nvarchar(max) NOT NULL,
                            ClassID int NOT NULL,
                            Phone nvarchar(max) NOT NULL,
                            Email nvarchar(max) NOT NULL,
                            FOREIGN KEY(ClassID) REFERENCES T_Class (ID)
                              )
                 第四、创建数据表:T_Teacher
                         USE [SchoolDB]
                         GO

                         CREATE TABLE T_Teacher(
                                ID int PRIMARY KEY IDENTITY(1,1) NOT NULL,
                                Name nvarchar(max) NOT NULL,
                                Address nvarchar(max) NOT NULL,
                               Phone nvarchar(max) NOT NULL,
                               Email nvarchar(max) NOT NULL,
                               ClassID int NOT NULL,
                                FOREIGN KEY(ClassID) REFERENCES T_Class(ID)
                            )

    4、利用EF,根据database first 原则生成实体类的步骤
    第一步、打开vs2012 ,新建一个控制台应用程序,并名为:EFDatabaseFirstTest

                 这里不再赘述,不会的网上查一下资料
    第二步:创建实体模型
                在第一步创建的项目名称上右击, 添加“新建项”→Ado.Net实体数据模型
                 命名为:Model1.edmx

    如下图所示:


    第三步:与现有的数据库进行连接生成EF实体
    在做这步之前,首先确定你是否已经有现有数据库
    (1)、选择从数据库生成实体数据模型

               
    (2)、新建连接到现有的数据库,


    (3)、点击下一步,选择我们要生成实体对应的表、试图、存储过程等,


    (4)、最后点击完成,则系统帮我们生成了数据库实体类以及EDMX的定义文件。
    生成的文件目录如下图所示:


    到现在我们前期的准备工作就结束了,接下来我们将使用EF帮我们生成的数据库网关来操作数据库了

    5、数据的增删改查操作
    (1)、插入数据

          /// <summary>
            /// 向数据库插入一条学生信息
            /// </summary>
          public  bool AddStudent()
            {
                //创建数据库访问网关
                //SchoolDBEntities在配置文件中(App.config中)
                using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
                {
                    //创建student一个实体
                    T_Student student = new T_Student()
                    {
                        ClassID = 1,
                        Email = "405325966@qq.com",
                        Name = "张三",
                        Phone = "63339236",
                        T_Class = new T_Class() { ID = 1, Name = "一班" }
                    };
    
                    //将创建的实体,放入网关的数据实体的集合          
                    schoolEntities.T_Student.Add(student);
                    //写回数据库
                  int k1=  schoolEntities.SaveChanges();
                  return k1 > 0;
                }
            }
    View Code

      (2)、编辑数据
    方法一:每次都需要对所有字段进行修改,效率低
    示例代码:

     /// <summary>
            /// eidt 编辑student信息
            /// </summary>
            /// <returns></returns>
          public bool EditStudent01()
          {
              //说明,编辑的时候需要给主键赋值
              //修改所有的字段
              //编辑
              //创建数据库访问网关
              //SchoolDBEntities在配置文件中
              using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
              {
    
                  T_Student student = new T_Student
                  {
                      ID =1,//编辑ID=1的学生的信息               
                      ClassID = 4,
                      Email = "tengxun@126.com",
                      Name = "李四",
                      Phone = "139******"
                  };
    
                  //将实体附加到对象管理器中
                  schoolEntities.T_Student.Attach(student);
                  //把当前实体的状态改为Modified
                  schoolEntities.Entry(student).State = EntityState.Modified;
                 int k1= schoolEntities.SaveChanges();
                 return k1 > 0;
    
    
              }
          }
    View Code

    方法二:编辑、修改部分字段(属性)
    示例代码:只是编辑Phone、Email两个字段

     public bool EditStudent02()
          {
              //说明,编辑的时候需要给主键赋值
              //修改所有的字段
              //编辑
              //创建数据库访问网关
              //SchoolDBEntities在配置文件中
              using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
              {
    
                  T_Student student = new T_Student
                  {
                      ID =1,//编辑ID=1的学生的信息               
                      ClassID = 4,
                      Email = "360@126.com",
                      Name = "李留",
                      Phone = "158******"
                  };
    
                  //将实体附加到对象管理器中
                  schoolEntities.T_Student.Attach(student);
                  //获取到user的状态实体,可以修改其状态 
                  var setEntry = ((IObjectContextAdapter)schoolEntities).ObjectContext.ObjectStateManager.GetObjectStateEntry(student);
                  //只修改实体的Name属性和Age属性 
                  //修改需要对主键赋值,注意:这里需要对所有字段赋值,没有赋值的字段会用NULL更新到数据库,当然数据库设计的时候字段允许为null才可以
                  setEntry.SetModifiedProperty("Email");
                  setEntry.SetModifiedProperty("Phone");
    
    
                 int k1= schoolEntities.SaveChanges();
                 return k1 > 0;
    
    
              }
          }
    View Code

    (3)、查询:查询通过LinQ查询
    //查询到学生对应的班级的外键,注意是使用的linq to ef ,它是生成的命令树,然后是生成的sql

                    var cls = (from c in schoolEntities.T_Class
                               where c.ID == 1
                               select c).SingleOrDefault<T_Class>();

    注意:只有调用了FirstOrDefault, First, Single, ToList, ToArray等函数才会执行对数据库的查询  
     
    示例代码:

     //查询获得一个实体
       public T_Class GetClass()
       {
           using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
           {
               T_Class classObj = (from c in schoolEntities.T_Class
                                   where c.ID == 2
                                   select c).SingleOrDefault<T_Class>();
               return classObj;
           }
       
       }
    
          /// <summary>
            /// 获取实体列表
            /// </summary>
            /// <returns></returns>
       public List<T_Class> GetClass02()
       {
           using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
           {
               var classObj = (from c in schoolEntities.T_Class select c).ToList<T_Class>();
               return classObj;
           }
    
       }
    View Code

    (4)、删除数据
      //删除,删除只需要主键即可

         /// <summary>
            /// 删除有两种方法,都在示例代码中
            /// </summary>
            /// <returns></returns>
       public bool deleteStudent()
       {
           //创建数据库访问网关
           //SchoolDBEntities在配置文件中
           using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
           {
               T_Student student = new T_Student()
               {
                   ID = 1
    
               };
               //将实体附加到对象管理器中
               schoolEntities.T_Student.Attach(student);
               //方法一:
               //schoolEntities.T_Teacher.Remove(teacher);
               //方法二:把当前实体的状态改为删除
               schoolEntities.Entry(student).State = EntityState.Deleted;
           int k1=schoolEntities.SaveChanges();//不论是方法一还是方法二 这一句代码都是必须的
           return k1 > 0;
    
           }
       }  
    View Code


    (5)、使用事务
     EF对事务进行了封装:context的saveChange()是有事务性的。

    示例代码:
    说明:添加多条记录的时候,最后可以只执行一次   schoolEntities.SaveChanges();
    示例代码:

          /// <summary>
            /// 使用事务
            /// </summary>
            /// <returns></returns>
       public bool UserTranAddStu()
       {
           //使用事务
           //创建数据库访问网关
           //SchoolDBEntities在配置文件中
           using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
           {
    
            
               //创建student一个实体
               T_Student student = new T_Student() { 
                  Email = "guo123@126.com",
        
              Name = "长城",
            Phone = "1201",
             ClassID=1
             
               };
               //创建student一个实体
               T_Student student01 = new T_Student()
               {
                   Email = "guo456@126.com",
              
                   Name = "万里",
                   Phone = "1202",
                   ClassID = 2
    
               };
               //将创建的实体,放入网关的数据实体的集合   
               schoolEntities.T_Student.Add(student);
               schoolEntities.T_Student.Add(student01);
               //写回数据库
            int k1= schoolEntities.SaveChanges();
            return k1 == 2;
    
           }
       }
    View Code

    上面的示例也可以写成:

     public bool UserTranAddStu02()
       {
           //使用事务
           //创建数据库访问网关
           //SchoolDBEntities在配置文件中
           using (SchoolDBEntities schoolEntities = new SchoolDBEntities())
           {
    
               List<T_Student> students = new List<T_Student>();
               //创建student一个实体
               T_Student student = new T_Student()
               {
                   Email = "guo123@126.com",
    
                   Name = "长城",
                   Phone = "1201",
                   ClassID = 1
    
               };
               students.Add(student);
               //创建student一个实体
               T_Student student01 = new T_Student()
               {
                   Email = "guo456@126.com",
    
                   Name = "万里",
                   Phone = "1202",
                   ClassID = 2
    
               };
               students.Add(student01);
               //将创建的实体,放入网关的数据实体的集合   
               students.ForEach(x => { schoolEntities.T_Student.Add(x); });     
                  //写回数据库
               int k1 = schoolEntities.SaveChanges();
               return k1 == students.Count;
    
           }
       }
    View Code

    6、扩展
    这里所说的扩展是指在现有的数据库中,新增数据表
    (1)、新建数据表

    use SchoolDB
    go
    create table T_Course
    (
    Id int primary key identity(1,1) not null,
    Name nvarchar(50) null
    )
    View Code

    处理办法
    (1)、添加T_Course.cs实体类
    方法:右击 解决方案中项目中的“Model1.edmx”文件 -->打开
    在打开的Model1.edmx[关系图1]的空白处 右击 选择“从数据库更新模型”
    选择新增的数据表,生成模型即可

    如下图所示:


    (2)、然后既可以按照上面所讲的方法insert、edit、delete、select 操作了。

       public bool AddCourse()
       {
           //创建数据库访问网关
           //SchoolDBEntities在配置文件中
       using(SchoolDBEntities context=new SchoolDBEntities())
       {
           //定义一个实体、、
           T_Course course = new T_Course() {  Name="领跑英语"};
    
           //添加到网关的实体数据集合
           context.T_Course.Add(course);
           //保存数据
           int k1 = context.SaveChanges();
           return k1 > 0;
       
       }
       }
    View Code
  • 相关阅读:
    一起谈.NET技术,JAVA与.NET的相互调用——TCP/IP相互调用基本架构 狼人:
    一起谈.NET技术,.NET异步编程:IO完成端口与BeginRead 狼人:
    一起谈.NET技术,VS2010自定义新建文件模版 狼人:
    一起谈.NET技术,理解.NET程序集的执行过程 狼人:
    一起谈.NET技术,JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯 狼人:
    一起谈.NET技术,用NuGet掌管你的Visual Studio扩展 狼人:
    一起谈.NET技术,Visual Studio 2010 中的代码约定设置 狼人:
    一起谈.NET技术,C#中的语言特性都是从何而来? 狼人:
    一起谈.NET技术,关于Winform下,获取Treeview中CheckBox选中项的技巧 狼人:
    一起谈.NET技术,ASP.NET MVC 3和Razor中的@helper 语法 狼人:
  • 原文地址:https://www.cnblogs.com/net064/p/8024150.html
Copyright © 2011-2022 走看看