EF的增删改查

创建上下文对象:TestDBEntities db = new TestDBEntities();

一、增:

    //1.1创建实体对象方式一  

       User uObj = new User()
       {    
           uName = "刘德华",    
           uLoginName = "aaa",    
           uPwd = "asdfasdfasdfsadf",    
           uIsDel = false,    
           uAddtime = DateTime.Now    
       };     

        //创建实体方式二         

    //User user = new User();
   //user.LoginName = "ssss";
   //user.Mail = "ssss";
   //user.PassWord = "ssss";
   //user.Plane = "ssss";
   //user.UserName = "ssss";
   //user.phone = "ssss"; 

         //1.2.1告诉EF咱们对上面的实体做一个插入操作    

        db.Users.Add(uObj);    

       //1.2.2告诉上下文把实体的变化保存到数据库里面去    

        db.SaveChanges();   

       //1.3 添加用户时可以关联导航属性:

            UserInfo与OrderInfo存在一对多关系 
            //创建一个用户
            //UserInfo userInfo = new UserInfo();
            //userInfo.UName = "yang";
            //告诉上下文我们对这个实体做添加操作
            //dbContext.UserInfo.Add(userInfo);
            //创建两个订单
            //OrderInfo order1 = new OrderInfo();
            //order1.Content = "shit1";
            //dbContext.OrderInfo.Add(order1);
            //OrderInfo order2 = new OrderInfo();
            //order2.Content = "shit2";
            //dbContext.OrderInfo.Add(order2);
            //关联三个实体
            //1、通过用户添加订单实体到自己的导航属性
            //userInfo.OrderInfo.Add(order1);
            //2、通过订单指定用户实体
            //order2.UserInfo = userInfo;
            ////order2.UserInfoID = userInfo.ID;

     

二、删除:

  EF中实现删除有三种方式,版本一、二都是根据主键删除,版本三是根据任意条件到数据库查询然后再根据查询的结果进行删除,实际上版本三也是根据查询出来的结果中的主键进行删除。

1 :根据主键删除方式一

    //实例化一个Users对象,并指定Id的值
    Users user = new Users() { Id = 1 };
    //将user附加到上下文对象中,并获得EF容器的管理对象
    var entry = db.Entry<User>(user);或者 var entry=db.Entry(user);
    //设置该对象的状态为删除
    entry.State = EntityState.Deleted;
    //以上两步可并作一步
     //dbContext.Entry<USER>(user).State = System.Data.EntityState.Modified;
    //保存修改
    db.SaveChanges(); 

2:根据主键删除方式二

      //实例化一个Users对象,并指定Id的值
      Users user = new Users() { Id = 1 };
      //将user附加到上下文对象中
      db.Users.Attach(user);
     //注意:附加的实体对象事先不能已经在上下文中,否则上下文会追踪到两个相同键名的实体对象而报错。
      //删除user对象
      Db.Users.Remove(user);
      //保存修改
      db.SaveChanges(); 

  3:先根据条件查询出来然后再删除

  //3.1 一下只删除一个

   // linq方式
      var user = (from v in db.Users
                        where v.ID == 14
                        select v).Single();
   //拉姆达方式
    //var user= db.Users.Where(u => u.ID==2).firstOrDefault();
      db.UserInfo.Remove(user);
      db.SaveChanges();
  //3.2一下删除一个或多个
  var list= db.Users.Where(u => u.Name ==”张三”);
  if (list != null && list.Any()) // Any作用:如果源序列包含任何元素,则为 true;否则为 false。
  {
    foreach (var item in list)
    {
      db.Users.Remove(item);
    }
  }
  db.SaveChanges();

  

三、修改:

//方式一:先将Id为2的Users数据查询出来,在修改。(这是代码最少的方式)

      var user = db.Users.Where(u => u.Id == 2).FirstOrDefault();
      //修改UserName属性
      user.UserName = "222222222222222";
      //保存修改 
      db.SaveChanges(); 
      //由于查询出来的实体对象本身就在上下文中,所以不需要再附加到上下文。 

//方式二:声明一个User实体

  USER user = new USES();
  user.LoginName = "ssss111--------";
  user.Mail = "ssss";
  user.PassWord = "ssss";
  user.Plane = "ssss";
  user.UserName = "ssss";
  user.cardNo = "ssss";
  user.phone = "ssss";
  user.ID = 8;//修改删除的时候必须指定id(主键)

  //3、告诉上下文咱们的对此实体进行更新操作。

  //db.Entry<USER>(user).State = System.Data.EntityState.Modified;

  //4、告诉上下文把实体的变化保存到数据库里面去。

  db.SaveChanges();//真正执行sql脚本的地方。

// 方式三 只修改部分字段

  USER user = new USES();
  user.LoginName = "ssss111--------";
  user.Mail = "ssss";
  user.PassWord = "ssss";
  user.Plane = "ssss";
  user.UserName = "ssss";
  user.cardNo = "ssss";
  user.phone = "ssss";
  db.USER.Attach(user);//附加到上下文里面来管理
  //指定要修改的字段(强类型方式)
  db.Entry<USER>(user).Property<string>(u => u.LoginName).IsModified = true;
  //指定要修改的字段(弱类型方式),推荐使用强类型因为有强类型校验。
  //db.Entry<USER>(user).Property("LoginName").IsModified = true;
     db.SaveChanges(); 
  //注意:上面的泛型<USER>、<string>可以省略,因为可以编译阶段会根据实体自动推断,如下
  //db.Entry (user).State = System.Data.EntityState.Modified;
  //db.Entry (user).Property (u => u.LoginName).IsModified = true;

方式四    空值字段处理,关闭实体合法性检查

   //1)创建出一个要修改的对象
   User use = new User() { uId = 8,uName="小白~~~"};
   //2)将对象加入 EF容器,并获取当前实体对象的状态管理对象
   DbEntityEntry<User> entry = db.Entry<User>(user);
   //3)设置该对象为未被修改过
   entry.State = System.Data.EntityState.Unchanged;
   //4)设置该对象的 uName属性为修改状态,同时 entry.State 被修改为 Modified 状态
  entry.Property("uName").IsModified = true;
   //5)关闭EF实体合法性检查(如果创建出来的要修改的数据有的字段没有赋值则关闭实体合法性检查,如果所有字段都赋值了则不用关闭EF实体合法性检查)
    db.Configuration.ValidateOnSaveEnabled = false;
  //6)重新保存到数据库 -- ef 上下文会根据实体对象的状态,根据 entry.State =Modified 的值生成对应的 update sql 语句.
    db.SaveChanges();

注意:增删改操作都需要执行db.SaveChange(),否则不会去操作数据库。

四、查询:

查询方式有两种,一种是拉姆达表达式(一般点出来),一种是linq(类似于sql)。

(一)linq 方式举例

IQueryable<USER> temp = from u in db.USER
                        where u.ID > 4
                        select u; 

(二)拉姆达表达式:

1、单行  

    var userLogin = db.T_UserLogin.Where(d => d.LoginID == loginID).FirstOrDefault();

2、多行()

1)var  list = db.Users.Where(u => u.uName == "刘德华").ToList();

2)List<User> list = db.Users.Where(u => u.uName == "刘德华").ToList();

3、连接查询:

1)linq连接查询: from a in db.User join b in db. UsersAddresses  on a.Id equals b.udid

2)拉姆达表达式连接查询:IQueryable<UsersAddress> addrs = db.User.Include("UsersAddresses").Where(a => a.Id == 1);

3)另一种连接查询:var list=db.User.Join(db. UsersAddresses,c=>c.Id,g=>g.udid,(c,g)=>new{Name=c.Name,GroupName=g.GroupName});  

查询还远远不只这点,有需要请百度linq查询系统学习。

五、增删改查的另一种方式,纯sql。

  当遇到复杂的需求,需要书写复杂语句,但有不特别熟悉EF语法时有两种方案:

  1.数据库中创建视图或存储过程

  2纯sql方式;

  //1)查询SqlQuery

  简单用法

  result.slList = db.Database.SqlQuery<DataTemp>("select Precision,Year,LandCover, sum(Area) as Area  from [EcoTypes]  where  LandCover=@type group by Precision, Year, LandCover", new SqlParameter("@type", "森林")).Select(d=> d.Area).ToList();

       复杂用法

//var sql = "select cc.GermID, cc.Name,cc.EnglishName, c.SamplingMethod,c.BatchID," +
// "Max(case c3.LocationID when 1 then c.DataValue*100 else 0 end) as '交通枢纽'," +
// "Max(case c3.LocationID when 2 then c.DataValue*100 else 0 end) as '居民区'," +
// "Max(case c3.LocationID when 3 then c.DataValue*100 else 0 end) as '文教区'," +
// "Max(case c3.LocationID when 4 then c.DataValue*100 else 0 end) as '城市绿地'," +
// "Max(case c3.LocationID when 5 then c.DataValue*100 else 0 end) as '中心商务区'," +
// "Max(case c3.LocationID when 6 then c.DataValue*100 else 0 end) as '商业区'," +
// "Max(case c3.LocationID when 7 then c.DataValue*100 else 0 end) as '旅游区'," +
// "Max(case c3.LocationID when 8 then c.DataValue*100 else 0 end) as '工业区'" +
// " from [dbo].T_GermData as c " +
// " inner join [dbo].T_Germ as cc on c.GermID=cc.GermID " +
// " inner join [dbo].[T_MicrobeLocations] as c3 on c3.LocationID=c.LocationID " +
// " where c.BatchID=1 and c.SamplingMethod=@SamplingMethod" +
// " group by cc.GermID, cc.Name, cc.EnglishName,c.SamplingMethod,c.BatchID";
//var sqlParams = new SqlParameter[]
//{
// new SqlParameter("@SamplingMethod",System.Data.SqlDbType.SmallInt) {Value= samplingMethod},
//};
//var data = db.Database.SqlQuery<GermTemp>(sql, sqlParams);

  如果需要更灵活或复杂,可以考虑在数据库写存储过程。

       //2)增删改:ExecuteSqlCommand

      db.Database.ExecuteSqlCommand("").ToString();

      详情请百度 db.Database. 此时会出现使用方式和相应的说明文字。  

六、linq学习资料整理

    LINQ的全称是Language Integrated Query,中文译成“语言集成查询”,主要用于查询。举一个简单的例子,比如说sql语句:select userName from t_user where userID = 1;这句sql语句可以分为哪几部分,他们各自的执行顺序是什么。当然有select,from,where三层,执行的顺序当然是先from ,再where,在select,所以将上述sql转成linq为:

    var query=   from user in DBcontext.t_user where user.userID == 1 select user;

3)linq学习资料整理:

       https://www.cnblogs.com/hao-1234-1234/p/11175410.html 

七、相关概念

1)数据持久化

      是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称;数据模型可以是任何数据结构或对象模型,存储模型可以是关系模型、XML、二进制流等;其实,简单来说,就是将数据存储到数据库中,为什么这么说呢?因为持久化就不是暂时的,而存储分为暂存和永存两个方面,暂存指的是存储到了计算机的内存中,电源关闭即丢失。而永存就是存储到了类似数据库里,数据就可以反复使用。除此以外,持久化封装了数据访问细节,为大多数业务逻辑提供面向对象的API。

   1. 通过持久化技术可以减少访问数据库数据次数,增加应用程序执行速度;

   2. 代码重用性高,能够完成大部分数据库操作; 

   3. 松散耦合,使持久化不依赖于底层数据库和上层业务逻辑实现,更换数据库时只需修改配置文件而不用修改代码。

八、问题与思考

         1 、建议从客户端(前端)、代码服务器(后台)、数据库服务器 三个方向思考问题,代码服务器觉得困难问题前端和数据库端都很简单。  

         2 、换一种技术路线,对EF困难的问题,对原生ADO代码可能不难。(注意,除非遇到无法解决的问题,一般不建议同时多种技术路线,减少学习难度,方便日后维护。)

    3、速度,当你遇到对速度的极高要求时,EF这种ORM框架,甚至大多数orm框架都不在实用,这时要返璞归真,最求极致的简单。但又要可控:开发进度可控,安全可控,后期可维护可能等。

    4、性能瓶颈和综合成本 

            1)综合考虑硬件:带宽、IO、内存、安全等,

      带宽:传递给前端数据尽可能少、前端代码压缩后在发布等,可以减少对带宽的压力。

              安全:物理隔离、代码逻辑权限机制、前端代码压缩、漏洞软件(appscan)、第三方图片服务器及其授权机制 等

    内存: 代码服务器 计算量较大时,可以分配一些计算量到客户端或数据库服务器(存储过程)。 

            2)综合考虑软件:技术体系选择、架构设计、框架选择、数据库设计、代码实现、后期运维难度 、源代码管理等因素。 

    技术体系: java、.net ,这里考虑到成本和规模选择.net

    开发工具:前端vscode 、后台 vs(太卡了)

    架构设计: 前后端完全分离 、mvc 等

    框架选择:后端成熟框架 webapi、前端成熟框架 vue、element、webpack、;

    数据库设计:数据库设计工具如 Powdesigner、数据库设计(物理位置、权限机制、分库、分表、字段、索引、临时表等)

      代码实现:文字规范、接口规范、功能实现

      运营维护:运维设备、运维工具软件

     源代码管理: 管理平台:国外github(网速、中英文障碍)。微软svn、国内gitee。

     这已经超过我目前的个人能力的,呵呵。

八、参考文章:

https://www.cnblogs.com/zhuyuchao/p/5634196.html

https://blog.csdn.net/weienjun/article/details/79170819

https://www.cnblogs.com/xiashengwang/archive/2012/07/28/2609161.html

原文地址:https://www.cnblogs.com/hao-1234-1234/p/8760985.html