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}");
});
}