EF中的 增删改

前言

初识EF操作数据库,虽然看了资料会用但是有些懵懂,闲下来仔细了解,才算真正懂得这是怎么一回事。 
r(查找)比较简单,就不再多说。

正文

DbContext:一个数据上下文

我们在EF中实例化一个继承自DbContext的上下文,这个上下文包含很多DbSet成员。我想说的是,对于同一个上下文,当其交使用SavaChanged方法互数据库时会把所有操作包含在一个事务内,事务的作用就是为了保证所有sql执行成功的,不成功则回滚。所以你在执行多个操作时大可放心不全部成功执行的问题。如:

db.UserInfo.Add(user);
db.User.Add(user);
db.SaveChanges();

这里我有一个需求:当用户注册时向两个表中插入数据,一个是用户基本信息表一个是用户的具体信息表。必须同时插入成功,不能出现一个表成功插入另一个表失败的情况,这个时候放心使用SavaChanged吧。

SavaChanged():一个数据提交方式

SavaChanged()用于提交数据。db.SavaChanged()返回值是数据库中有几条数据被影响,所以你可以用db.SavaChanged()>0来判断是否成功的插入、修改、删除了数据。

EntityState:5个状态值

当SavaChanged()方法执行期间,他会查看当前Entity的EntityState的值,决定是去新增(Added)、修改(Modified)、删除(Deleted)、什么也不做。 
如:

  db.Entry(userinfo).State = EntityState.Added;
  • 1

打开EntityState 
这里写图片描述
Detached,当前实体没有存在于dbContext(数据库)中 
Unchanged,当前实体属性值没有发生改变 
Added,标记为增加状态,下次saveChange将添加到数据库中 
Deleted,标记删除状态,下次saveChange将删除 
Modified,标记为更改状态,下次将更新 
对于Detached:

  UserInfo userinfo = new UserInfo();
 EntityState userinfoState2 = db.Entry(userinfo).State;

这里userinfo 和db没有任何关系,所以userinfoState2值是Detached。

3个EF方法

Attach是连接,可以看成从数据库读取出了实体(但没有操作数据库) 
Add,其实也就是将实体状态改为added。 
remove,所操作的实体不能是Detached状态(也就是说实体必须存在于db中) 
对于Attach: 
这里写图片描述
Attach,执行下面代码看下数据库sql语句:

            UserInfo userinfo6 = new UserInfo();

            userinfo6.ID = 4;
            db.UserInfo.Attach(userinfo6);
            Console.WriteLine(db.Entry(userinfo6).State);

这里写图片描述
数据库监视器并没有监视到sql,所以Attach是不操作数据库的。当savechange时才会操作生成sql交互数据库。

注意:Attach后的实体状态是Unchanged。当你想要修改(modified)和删除(remove)数据,必须修改实体状态。

扫描二维码关注公众号,回复: 3063530 查看本文章

CUD操作

增加

    // 第一种方式,建议使用
    UserInfo userinfo=new UserInfo(){ Name="苏轼"};
    db.UserInfo.Add(userinfo);
    db.SavaChanged();
    // 第二种方式:设置状态state
    db.Entry(userinfo).State = EntityState.Added;
    db.SavaChanged();

注意:SavaChanged()时会进行数据回调,以便你在进行增加(或修改)后可以马上取到数据进行使用。假如你数据库的id是自增的,上面增加成功后userinfo的id就被赋予了数据库的值。这是很有用的,比如用户上传了文件后要返回文件id的情境。

修改

  // 先查再改,数据库操作两次,不建议
  UserInfo userinfo = db.UserInfo.FirstOrDefault(u => u.ID == 1);
  userinfo.Name = "苏轼";
  db.SavaChanged();
  // 第二种方式,使用Attach,数据库操作一次,建议
  UserInfo userinfo = new UserInfo() { ID = 1,Name = "苏轼" };
  db.UserInfo.Attach(userinfo);
  db.SavaChanged();
  // 第三种,直接设置实体状态,数据库操作一次,建议
   UserInfo userinfo4 = new UserInfo(){ ID = 1,Name = "苏轼" };
   db.Entry(userinfo4).State = System.Data.Entity.EntityState.Modified;
   db.SavaChanged();

上面几种都会修改实体的所有字段并不灵活,有时候需求是只需要修改其中一两个字段而已,怎么办呢?我们可以分别设置字段的IsModified值来控制字段是否是可修改的。以Attach方式为例:

   UserInfo userinfo = new UserInfo() { ID = 1,Name = "苏轼" };
   db.UserInfo.Attach(userinfo);
   db.Entry(userinfo4).Property("Sex").IsModified = false;
   db.Entry(userinfo4).Property("Name").IsModified = true;
   // 这里我们还可以使用lambda
   db.Entry(model).Property(u => u.Status).IsModified = false;
   db.SavaChanged();

上面的代码,不会修改Sex、Name、Status的值,这种方式对于避免了不必要的字段修改。

删除

    // 第一种,remove
    db.UserInfo.Attach(userinfo6);
    db.UserInfo.Remove(userinfo6);
    db.SavaChanged();
    // 第二种,设置状态
    db.Entry(userinfo6).State = EntityState.Deleted;
    db.SavaChanged();
    // 第三种,先查出来再改,这是微软推荐方法,因为上两种,不管附加还是设置状态,数据库不存在这个实体程序就会报错
    UserInfo userinfo6 = db.UserInfo.FirstOrDefault(u => u.ID == 1);
    if (userinfo6 != null)
        db.UserInfo.Remove(userinfo6);      

当你如果你确定这个数据在数据库中存在,用前两种方式的确是最好的,假如你进行了异常检测如使用了try-catch,也可以使用前两种

总结

  1. 同一个DbContext上下文操作中使用事务保证操作完整性。
  2. 使用SavaChanged进行数据提交
  3. 数据提交时是根据实体(或者说是字段)的EntityState状态来进行相应的增加、删除、修改操作的。可以直接修改其状态,也可以通过Add、Attach、Remove修改其状态

猜你喜欢

转载自blog.csdn.net/LeehomeYU/article/details/81639217