EFCore范型数据仓储和DBContext优化

DB Frist

在这里插入图片描述
定义IRespository接口
在这里插入图片描述
BaseContext.cs
需要继承 DbContext

1、重写 OnConfiguring 方法,指定数据库
我们在查询只读数据的时候,可以取消EF实体追踪。
2、 重写 OnModelCreating 利用反射获取命名空间下的所有的public类,此处可以注入一个标记来识别是否是实体类。将所有实体放入EF中。
3、 public void Detach() 方法是在SaveChanges后更改EF追踪实体标记的,用来取消追踪的 => Added、Detached、UnChanged… 将所有Save后的对象的标记改成Detached。
4、重写 SaveChanges() 方法,此处EF在保存前都会进行变更追踪,所以优化是在保存前先关闭,在保存后开启。ChangeTracker.AutoDetectChangesEnabled = false/true;

在这里插入图片描述

public class BaseDbContext : DbContext

protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseMySql("server=xxx;uid=root;pwd=xxx;database=xxx")
		//查询只读数据的时候取消实体追踪
		.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    //var assembly = Assembly.GetExecutingAssembly();
    var assembly = Assembly.Load("EF6.Entity");
    foreach (Type type in assembly.ExportedTypes)
    {
        if (type.IsClass && (type.Name != "xxx"))
        {
            var method = modelBuilder.GetType().GetMethods().Where(x => x.Name == "Entity").FirstOrDefault();
            if (method != null)
            {
                method = method.MakeGenericMethod(new Type[] { type });
                method.Invoke(modelBuilder, null);
            }
        }
    }
    base.OnModelCreating(modelBuilder);
}

public void Detach()
{
    ChangeTracker.Entries().ToList().ForEach(aEntry =>
    {
        var temp = aEntry;
        if (aEntry.State != EntityState.Detached)
            aEntry.State = EntityState.Detached;
    });
}

public override int SaveChanges()
{
    ChangeTracker.AutoDetectChangesEnabled = false;
    int count = base.SaveChanges();
    Detach();
    ChangeTracker.AutoDetectChangesEnabled = true;
    return count;
}

public async override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
    ChangeTracker.AutoDetectChangesEnabled = false;
    int count = await base.SaveChangesAsync(cancellationToken);
    Detach();
    ChangeTracker.AutoDetectChangesEnabled = true;
    return count;
}

Respository.cs

public class EFBaseRepository<T> : IRepository<T> where T : class

 //数据库上下文
 internal BaseDbContext context;
 //数据集
 internal DbSet<T> dbSet;
 //构造
 public EFBaseRepository()
 {
     this.context = GetContext();
     this.dbSet = context.Set<T>();
 }
private BaseDbContext GetContext()
{
     DbContextOptionsBuilder builder = new DbContextOptionsBuilder();
     builder.EnableSensitiveDataLogging();
     return new BaseDbContext(builder.Options);
}
public void Delete(object id)
{
    T entityToDelete = dbSet.Find(id);
    Delete(entityToDelete);
    context.SaveChanges();
}

public void Delete(T entity)
{
    //实体追踪
    if (context.Entry(entity).State == EntityState.Detached)
    {
        dbSet.Attach(entity);
    }
    //删除
    dbSet.Remove(entity);
    context.SaveChanges();
}

public void Delete(IEnumerable<T> entities)
{
    dbSet.RemoveRange(entities);
}

public T GetByKey(object key)
{
    return dbSet.Find(key);
}

/// <summary>
/// 取消实体追踪
/// </summary>
/// <returns></returns>
public IQueryable<T> GetIQueryable()
{
    return dbSet;
}

public void Insert(T entity)
{
    dbSet.Add(entity);
    context.SaveChanges();
}

public async void InsertAsync(T entity)
{
    await dbSet.AddAsync(entity);
}

public void Insert(IEnumerable<T> entities)
{
    dbSet.AddRange(entities);
    context.SaveChanges();
}

public async void InsertAsync(IEnumerable<T> entities)
{
    await dbSet.AddRangeAsync(entities);
    context.SaveChanges();
}

public void Update(T entity)
{
    dbSet.Attach(entity);
    context.Entry(entity).State = EntityState.Modified;
    context.SaveChanges();
}

public List<T> GetDataList()
{
    return dbSet.ToList();
}
public virtual IEnumerable<T> Get(
Expression<Func<T, bool>> filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
string includeProperties = "", int topNum = 0)
{
    IQueryable<T> query = dbSet;

    if (filter != null)
    {
        query = query.Where(filter);
    }

    foreach (var includeProperty in includeProperties.Split
        (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
    {
        query = query.Include(includeProperty);
    }

    if (orderBy != null)
    {
        query = orderBy(query);
    }
    if (topNum != 0)
    {
        return query.Take(topNum);
    }
    else
    {
        return query.ToList();
    }
}

省略接口,Bussiness.cs

public EFBaseRepository<T> _service=new EFBaseRepository<T>();

public BaseBussiness()
{
}

public void Delete(object id)
{
    _service.Delete(id);
}

public void Delete(T entity)
{
    _service.Delete(entity);
}

public void Delete(IEnumerable<T> entities)
{
    _service.Delete(entities);
}

public T GetByKey(object key)
{
    return _service.GetByKey(key);
}

public List<T> GetDataList()
{
    return _service.GetDataList();
}

public void Insert(T entity)
{
    _service.Insert(entity);
}

public void Insert(IEnumerable<T> entities)
{
    _service.Insert(entities);
}

public void Update(T entity)
{
    _service.Update(entity);
}

测试 People.cs

public void Add(WechatUser wechatUser)
{
    _service.Insert(wechatUser);
}

public List<WechatUser> GetList()
{
   return _service.GetDataList();
}

public void InsertList(List<WechatUser> list)
{
    _service.Insert(list);
}

Program.cs

static void Main(string[] args)
{
    IPeopleBussiness bussiness = new PeopleBussiness();
    List<WechatUser> queryable = bussiness.GetList();
    queryable.ForEach(x => {
        Console.WriteLine($"{x.PhoneNumber} {x.WechatUserName}");
    });
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值