EFCore的常用语法

一.生成模式
  • 从实体到数据,使用T4模板生成
  • 数据到实体,使用上下文(context)交互(继承DBcontext)
  • EF实体框架有3种类型,Data First、Model First、Code First
二.增删改查   2.1 新增(Insert)
using(context con = new context())){
    Model modelName= new Model{
        对象属性 = 值
        ......
    }
    db.Model.Add(名称);//提交到内存
    db.SaveChanges();//提交到数据库
    return modelName.Key;
}

 

注:如果数据库ID主键为自增,可以在EF添加后直接读取modelName.Key主键值,EF会根据自增自动回写主键值。 2.2 查询(Select)   2.21 语义:使用linq查询,返回集合。 #简单查询单个值
using(context con = new context())){
    return con.Model.Where(linq表达式).FirstOrDefault();
}

 

#简单查询多个值
using(context con = new context())){
    return con.Model.Where(linq表达式).FirstOrDefault();
}

 

#直接查询到DTO对象
using(context con = new context())){
    return con.Model.Where(linq表达式).Select(q=>new DTOModel(){
        dtoModelField1 = q.Field1,
        dtoModelField2 = q.Field2,
        ......
    })FirstOrDefault();
}

 

#使用let进行子查询
using(context con = new context())){
    return con.Model.Where(linq表达式).Select(q=>new DTOModel(){
        dtoModelField1 = q.Field1,
        dtoModelField2 = q.Field2,
        ......
    })FirstOrDefault();
    var result = from modelName1 in con.Model1
                  let modelItemList = from modelName2 in con.Model2
                         where modelName2.foreignKey == modelName1.key
                        select new DTO.DTO_ModelItem() {
                           key = modelName2.BlogMeid,
                           field = modelName2.fieldName,
                           ......
                        }
             select new DTO_Model()
             {
                  key = modelName1.BlogMeid,
                  field = modelName1.fieldName,
                  item = modelItemList.Tolist()
             };
    return result.ToList();
}

 

#使用Join进行内连接查询
sing(context con = new context())){
    var result = from modelName1 in con.Model1
                 join modelName2 in con.Model2
                 on modelName1.foreignKey equals modelName2.key
                 select new DTO_Model()
                 {
                      key = modelName1.BlogMeid,
                      field1 = modelName1.fieldName1,
                      filed2 = modelName2.fieldName1,
                      ......
                 };
}

 

#使用Join + into 进行左外连接查询
using(context con = new context())){
    var result = from modelName1 in con.Model1
                 join modelName2 in con.Model2
                 on modelName1.foreignKey equals modelName2.key
                 into modelName3
                 from modelName4 in modelName3.DefaultIfEmpty()
                 select new DTO_Model()
                 {
                       key = modelName1.BlogMeid,
                      field1 = modelName1.fieldName1,
                      filed2 = modelName4.fieldName1,
                      ......
                 };
}

注:DefaultIfEmpty操作符能够为实序列提供一个默认的元素,如果不使用default关键字,需要在其当空时指定默认对象值。

modelName3.DefaultIfEmpty(new Model2(){
     key = "defaultfieldValue",
     field1 = "defaultfieldValue",
}}))

 

2.22 如果数据仅用于查询,而不会在后续更新删除,可以使用AsNoTracking() 直接修改EF模型状态,以减少跟踪对象状态改变而导致的性能损耗。
using(context con = new context())){
    db.Model.AsNoTracking().Where(user=>user.field=='fieldValue').ToList();
}

 

2.3 更新(Update)   1.查询数据后修改
using(context con = new context())){
    var Model =  con.Model.Where(linq表达式).FirstOrDefault();
    Model.field="fieldValue";
    con.SaveChanges();
}

 

2.已知ID对象修改 1.查询数据后修改
1.查询数据后修改
using(context con = new context())){
Model modelName = new Model(){
    id=1,
    field = "fieldValue"
};
//Attach:将给定实体以System.Data.EntityState.Unchanged状态附加到上下文中
con.Attach(modelName);
/或者
con.Entry(modelName).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
con.SaveChanges();
}

 

注:以上写法,如果在Model定义中未包含其他属性,EF会将其他属性全部清空,如果只需要修改定义的属性,可以使用下面这种写法
using(context con = new context())){
    //新建模型实体
    Model modelName = new Model(){
        id=1,
        field = "fieldValue"
    };
    //修改模型状态为尚未经过修改
    con.Entry(modelName).State = EntityState.Unchanged;
    //告诉EF,哪些列做了修改
    con.Entry(modelName).Property(p => p.filed).IsModified = true;
    con.SaveChanges();
}

 

2.4 删除(Delete)   1.未知主键数据,查询数据后删除
//删除单个数据
using(context con = new context())){
    var modelName =  con.Model.Where(linq表达式).FirstOrDefault();
    con.Remove(modelName);
    con.SaveChanges();
}
//删除多个数据
using(context con = new context())){
    var modelName =  con.Model.Where(linq表达式).ToList();
    con.RemoveRange(modelName);
    con.SaveChanges();
}

 

注:EF中Remove(Add,Update)Range等都是一条条执行SQL执行的,如果需要操作大量数据考虑效率,建议使用con.Database.ExecuteSqlCommand("SQL 语句")来直接执行。   2.已知主键数据删除
using(context con = new context())){
Model modelName = new Model(){
    id=1
};
//将给定实体以System.Data.EntityState.Unchanged状态附加到上下文中
con.Remove(modelName);
con.Entry(modelName).State = Microsoft.EntityFrameworkCore.EntityState.Deleted;
con.SaveChanges();
}

 

三.Model方法拓展   创建相同partial的Model类进行二次拓展。如果在实体模板类书写,会在重写生成模板后丢失。   四:EF中Model实体状态   EF中对实体状会有4种状态:
  1. Added:对象为新对象,并且已添加到对象上下文,但尚未调用 
  2. Deleted:对象已从对象上下文中删除
  3. Detached:对象存在,但没有被跟踪。 在创建实体之后、但将其添加到对象上下文之前,该实体处于此状态
  4. Modified:对象上的一个标量属性已更改,但尚未调用 
  5. Unchanged: 此对象尚未经过修改自对象附加到上下文中后,或自上次调用 (调用了SaveChange方法后所有的对象都改为Unchanged状态)
  五.即时加载与延迟加载   1.概念: 即时加载:即时执行SQL语句,获取数据 用法:使用List<实体对象> 接收返回数据 举例:List<实体对象> 名称 = db.实体对象.Where(linq表达式).ToList(); 延迟加载:按需加载,执行SQL语句 用法:使用system.data.entity.infrastructure.Dbquery 接收返回数据(DBquery实现了IQueryable接口) 举例:Dbquery 名称 = db.实体对象.Where(linq表达式) AS Dbquery   2.优缺点。 1.贪婪加载:
  • 减少数据访问的延迟,在一次数据库的访问中返回所有的数据。
  • 一次性读取所有相关的数据,可能导致部分数据实际无需用到,从而导致读取数据的速度变慢,效率变低
2.延迟加载:
  • 只在需要读取关联数据的时候才进行加载
  • 可能因为数据访问的延迟而降低性能,因为循环中,每一条数据都会访问一次数据库,导致数据库的压力加大
2.1 延迟加载-优点 2.11 针对多条件的延迟加载 如果针对一条查询结果,需要进行多次查询(比如说嵌套排序),使用延迟加载,会在所有SQL 拼接 完成后一次性执行,减少数据库访问次数。 2.12 针对外键的延迟加载 针对一条外键查询,只有在真正取用外键表数据的时候,才会进行外键查询 当外键对象数据重复时,只执行一次SQL语句。 2.13 延迟加载-缺点 表现:当外键对象数据不重复,会大量执行SQL语句。 解决方法:Include(关联对象) 联接多张表,一次性查询即可。 3.开启或者关闭延迟加载
Context ctx = new Context();
ctx.DeferredLoadingEnabled = false;
4.针对外键懒加载字段的某个字段进行实时加载
db.context.Include(c=>c.外键对象).Include(c=>c.外键对象)...
5.针对外键实时加载字段的某个字段进行懒加载   6. AssociateWith 用于筛选为特定关系检索到的对象。   7.LoadWith 用于立即加载与主目标相关的数据
上一篇:抖音数据采集接口


下一篇:【案例】Python检测二维码