mirror of
https://gitee.com/dotnetchina/OpenAuth.Net.git
synced 2025-11-08 02:14:44 +08:00
同步OpenAuth.Core最新代码
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenAuth.Repository.Core;
|
||||
@@ -29,7 +30,7 @@ namespace OpenAuth.Repository
|
||||
return Filter(exp);
|
||||
}
|
||||
|
||||
public bool IsExist(Expression<Func<T, bool>> exp)
|
||||
public bool Any(Expression<Func<T, bool>> exp)
|
||||
{
|
||||
return _context.Set<T>().Any(exp);
|
||||
}
|
||||
@@ -37,7 +38,7 @@ namespace OpenAuth.Repository
|
||||
/// <summary>
|
||||
/// 查找单个,且不被上下文所跟踪
|
||||
/// </summary>
|
||||
public T FindSingle(Expression<Func<T, bool>> exp)
|
||||
public T FirstOrDefault(Expression<Func<T, bool>> exp)
|
||||
{
|
||||
return _context.Set<T>().AsNoTracking().FirstOrDefault(exp);
|
||||
}
|
||||
@@ -61,7 +62,7 @@ namespace OpenAuth.Repository
|
||||
/// <summary>
|
||||
/// 根据过滤条件获取记录数
|
||||
/// </summary>
|
||||
public int GetCount(Expression<Func<T, bool>> exp = null)
|
||||
public int Count(Expression<Func<T, bool>> exp = null)
|
||||
{
|
||||
return Filter(exp).Count();
|
||||
}
|
||||
@@ -116,7 +117,6 @@ namespace OpenAuth.Repository
|
||||
Save();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 实现按需要只更新部分更新
|
||||
/// <para>如:Update(u =>u.Id==1,u =>new User{Name="ok"});</para>
|
||||
@@ -132,7 +132,7 @@ namespace OpenAuth.Repository
|
||||
{
|
||||
_context.Set<T>().Where(exp).Delete();
|
||||
}
|
||||
|
||||
|
||||
public void Save()
|
||||
{
|
||||
try
|
||||
@@ -169,7 +169,7 @@ namespace OpenAuth.Repository
|
||||
return dbSet;
|
||||
}
|
||||
|
||||
public int ExecuteSql(string sql)
|
||||
public int ExecuteSqlRaw(string sql)
|
||||
{
|
||||
return _context.Database.ExecuteSqlRaw(sql);
|
||||
}
|
||||
@@ -193,5 +193,129 @@ namespace OpenAuth.Repository
|
||||
{
|
||||
return _context.Query<T>().FromSqlRaw(sql, parameters);
|
||||
}
|
||||
|
||||
#region 异步实现
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> ExecuteSqlRawAsync(string sql)
|
||||
{
|
||||
return await _context.Database.ExecuteSqlRawAsync(sql);
|
||||
}
|
||||
|
||||
public async Task<int> AddAsync(T entity)
|
||||
{
|
||||
if (entity.KeyIsNull())
|
||||
{
|
||||
entity.GenerateDefaultKeyVal();
|
||||
}
|
||||
|
||||
_context.Set<T>().Add(entity);
|
||||
return await SaveAsync();
|
||||
//_context.Entry(entity).State = EntityState.Detached;
|
||||
}
|
||||
|
||||
public async Task<int> BatchAddAsync(T[] entities)
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
if (entity.KeyIsNull())
|
||||
{
|
||||
entity.GenerateDefaultKeyVal();
|
||||
}
|
||||
}
|
||||
|
||||
await _context.Set<T>().AddRangeAsync(entities);
|
||||
return await SaveAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步更新
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> UpdateAsync(T entity)
|
||||
{
|
||||
var entry = this._context.Entry(entity);
|
||||
entry.State = EntityState.Modified;
|
||||
|
||||
//如果数据没有发生变化
|
||||
if (!this._context.ChangeTracker.HasChanges())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return await SaveAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步删除
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> DeleteAsync(T entity)
|
||||
{
|
||||
_context.Set<T>().Remove(entity);
|
||||
return await SaveAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步保存
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public async Task<int> SaveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var entities = _context.ChangeTracker.Entries()
|
||||
.Where(e => e.State == EntityState.Added
|
||||
|| e.State == EntityState.Modified)
|
||||
.Select(e => e.Entity);
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var validationContext = new ValidationContext(entity);
|
||||
Validator.ValidateObject(entity, validationContext, validateAllProperties: true);
|
||||
}
|
||||
|
||||
return await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (ValidationException exc)
|
||||
{
|
||||
Console.WriteLine($"{nameof(Save)} validation exception: {exc?.Message}");
|
||||
throw (exc.InnerException as Exception ?? exc);
|
||||
}
|
||||
catch (Exception ex) //DbUpdateException
|
||||
{
|
||||
throw (ex.InnerException as Exception ?? ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据过滤条件获取记录数
|
||||
/// </summary>
|
||||
public async Task<int> CountAsync(Expression<Func<T, bool>> exp = null)
|
||||
{
|
||||
return await Filter(exp).CountAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AnyAsync(Expression<Func<T, bool>> exp)
|
||||
{
|
||||
return await _context.Set<T>().AnyAsync(exp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找单个,且不被上下文所跟踪
|
||||
/// </summary>
|
||||
public async Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> exp)
|
||||
{
|
||||
return await _context.Set<T>().AsNoTracking().FirstOrDefaultAsync(exp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -15,29 +15,30 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OpenAuth.Repository.Interface
|
||||
{
|
||||
public interface IRepository<T> where T : class
|
||||
{
|
||||
T FindSingle(Expression<Func<T, bool>> exp = null);
|
||||
bool IsExist(Expression<Func<T, bool>> exp);
|
||||
/// <summary>
|
||||
/// 返回一个单独的实体,如果记录多于1个则取第一个
|
||||
/// </summary>
|
||||
T FirstOrDefault(Expression<Func<T, bool>> exp = null);
|
||||
/// <summary>
|
||||
/// 判断指定条件的记录是否存在
|
||||
/// </summary>
|
||||
bool Any(Expression<Func<T, bool>> exp);
|
||||
IQueryable<T> Find(Expression<Func<T, bool>> exp = null);
|
||||
|
||||
IQueryable<T> Find(int pageindex = 1, int pagesize = 10, string orderby = "",
|
||||
Expression<Func<T, bool>> exp = null);
|
||||
|
||||
int GetCount(Expression<Func<T, bool>> exp = null);
|
||||
|
||||
int Count(Expression<Func<T, bool>> exp = null);
|
||||
void Add(T entity);
|
||||
|
||||
void BatchAdd(T[] entities);
|
||||
|
||||
/// <summary>
|
||||
/// 更新一个实体的所有属性
|
||||
/// </summary>
|
||||
void Update(T entity);
|
||||
|
||||
void Delete(T entity);
|
||||
|
||||
|
||||
@@ -48,6 +49,7 @@ namespace OpenAuth.Repository.Interface
|
||||
/// <param name="where">更新条件</param>
|
||||
/// <param name="entity">更新后的实体</param>
|
||||
void Update(Expression<Func<T, bool>> where, Expression<Func<T, T>> entity);
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除
|
||||
/// </summary>
|
||||
@@ -55,19 +57,35 @@ namespace OpenAuth.Repository.Interface
|
||||
|
||||
void Save();
|
||||
|
||||
int ExecuteSql(string sql);
|
||||
|
||||
/// <summary>
|
||||
int ExecuteSqlRaw(string sql);
|
||||
|
||||
/// <summary>
|
||||
/// 使用SQL脚本查询
|
||||
/// </summary>
|
||||
/// <typeparam name="T"> T为数据库实体</typeparam>
|
||||
/// <returns></returns>
|
||||
IQueryable<T> FromSql(string sql, params object[] parameters);
|
||||
/// <summary>
|
||||
/// 使用SQL脚本查询
|
||||
/// </summary>
|
||||
/// <typeparam name="T"> T为非数据库实体,需要在DbContext中增加对应的DbQuery</typeparam>
|
||||
/// <returns></returns>
|
||||
|
||||
/// <summary>
|
||||
/// 使用SQL脚本查询
|
||||
/// </summary>
|
||||
/// <typeparam name="T"> T为非数据库实体,需要在DbContext中增加对应的DbQuery</typeparam>
|
||||
/// <returns></returns>
|
||||
IQueryable<T> Query(string sql, params object[] parameters);
|
||||
|
||||
|
||||
#region 异步接口
|
||||
|
||||
Task<int> ExecuteSqlRawAsync(string sql);
|
||||
Task<int> AddAsync(T entity);
|
||||
Task<int> BatchAddAsync(T[] entities);
|
||||
Task<int> UpdateAsync(T entity);
|
||||
Task<int> DeleteAsync(T entity);
|
||||
Task<int> SaveAsync();
|
||||
Task<int> CountAsync(Expression<Func<T, bool>> exp = null);
|
||||
Task<bool> AnyAsync(Expression<Func<T, bool>> exp);
|
||||
Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> exp);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
// Created : 04-29-2016
|
||||
//
|
||||
// Last Modified By : yubaolee
|
||||
// Last Modified On : 04-29-2016
|
||||
// Last Modified On : 12-15-2020
|
||||
// Contact : Microsoft
|
||||
// File: IUnitWork.cs
|
||||
// ***********************************************************************
|
||||
@@ -12,12 +12,14 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using OpenAuth.Repository.Core;
|
||||
|
||||
namespace OpenAuth.Repository.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 工作单元接口
|
||||
/// 使用详见:http://doc.openauth.me/core/unitwork.html
|
||||
/// <para> 适合在一下情况使用:</para>
|
||||
/// <para>1 在同一事务中进行多表操作</para>
|
||||
/// <para>2 需要多表联合查询</para>
|
||||
@@ -25,18 +27,39 @@ namespace OpenAuth.Repository.Interface
|
||||
/// </summary>
|
||||
public interface IUnitWork
|
||||
{
|
||||
/// <summary>
|
||||
/// EF默认情况下,每调用一次SaveChanges()都会执行一个单独的事务
|
||||
/// 本接口实现在一个事务中可以多次执行SaveChanges()方法
|
||||
/// </summary>
|
||||
void ExecuteWithTransaction(Action action);
|
||||
/// <summary>
|
||||
/// 返回DbContext,用于多线程等极端情况
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
OpenAuthDBContext GetDbContext();
|
||||
T FindSingle<T>(Expression<Func<T, bool>> exp = null) where T:class;
|
||||
bool IsExist<T>(Expression<Func<T, bool>> exp) where T:class;
|
||||
/// <summary>
|
||||
/// 返回一个单独的实体,如果记录多于1个则取第一个
|
||||
/// </summary>
|
||||
T FirstOrDefault<T>(Expression<Func<T, bool>> exp = null) where T:class;
|
||||
/// <summary>
|
||||
/// 判断指定条件的记录是否存在
|
||||
/// </summary>
|
||||
bool Any<T>(Expression<Func<T, bool>> exp) where T:class;
|
||||
IQueryable<T> Find<T>(Expression<Func<T, bool>> exp = null) where T:class;
|
||||
|
||||
IQueryable<T> Find<T>(int pageindex = 1, int pagesize = 10, string orderby = "",
|
||||
Expression<Func<T, bool>> exp = null) where T:class;
|
||||
|
||||
int GetCount<T>(Expression<Func<T, bool>> exp = null) where T:class;
|
||||
int Count<T>(Expression<Func<T, bool>> exp = null) where T:class;
|
||||
|
||||
/// <summary>
|
||||
/// 新增对象,如果Id为空,则会自动创建默认Id
|
||||
/// </summary>
|
||||
void Add<T>(T entity) where T:BaseEntity;
|
||||
|
||||
/// <summary>
|
||||
/// 批量新增对象,如果对象Id为空,则会自动创建默认Id
|
||||
/// </summary>
|
||||
void BatchAdd<T>(T[] entities) where T:BaseEntity;
|
||||
|
||||
/// <summary>
|
||||
@@ -49,18 +72,25 @@ namespace OpenAuth.Repository.Interface
|
||||
|
||||
/// <summary>
|
||||
/// 实现按需要只更新部分更新
|
||||
/// <para>如:Update<T>(u =>u.Id==1,u =>new User{Name="ok"}) where T:class;</para>
|
||||
/// <para>如:Update<User>(u =>u.Id==1,u =>new User{Name="ok"})</para>
|
||||
/// <para>该方法内部自动调用了SaveChanges(),需要ExecuteWithTransaction配合才能实现事务控制</para>
|
||||
/// </summary>
|
||||
/// <param name="where">更新条件</param>
|
||||
/// <param name="entity">更新后的实体</param>
|
||||
void Update<T>(Expression<Func<T, bool>> where, Expression<Func<T, T>> entity) where T:class;
|
||||
/// <summary>
|
||||
/// 批量删除
|
||||
/// <para>该方法内部自动调用了SaveChanges(),需要ExecuteWithTransaction配合才能实现事务控制</para>
|
||||
/// </summary>
|
||||
void Delete<T>(Expression<Func<T, bool>> exp) where T:class;
|
||||
|
||||
void Save();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 该方法不支持EF自带的事务,需要ExecuteWithTransaction配合才能实现事务控制,详见:http://doc.openauth.me/core/unitwork.html
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
int ExecuteSql(string sql);
|
||||
|
||||
/// <summary>
|
||||
@@ -75,5 +105,15 @@ namespace OpenAuth.Repository.Interface
|
||||
/// <typeparam name="T"> T为非数据库实体,需要在DbContext中增加对应的DbQuery</typeparam>
|
||||
/// <returns></returns>
|
||||
IQueryable<T> Query<T>(string sql, params object[] parameters) where T : class;
|
||||
|
||||
#region 异步接口
|
||||
|
||||
Task<int> ExecuteSqlRawAsync(string sql);
|
||||
Task<int> SaveAsync();
|
||||
Task<int> CountAsync<T>(Expression<Func<T, bool>> exp = null) where T : class;
|
||||
Task<bool> AnyAsync<T>(Expression<Func<T, bool>> exp) where T : class;
|
||||
Task<T> FirstOrDefaultAsync<T>(Expression<Func<T, bool>> exp) where T : class;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ using OpenAuth.Repository.Interface;
|
||||
|
||||
namespace OpenAuth.Repository.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// Repository测试基类
|
||||
/// 测试用于测试DbContext、UnitWork、Repository,如果需要测试业务逻辑,请使用OpenAuth.App里面的单元测试
|
||||
/// </summary>
|
||||
public class TestBase
|
||||
{
|
||||
protected AutofacServiceProvider _autofacServiceProvider;
|
||||
@@ -19,6 +23,7 @@ namespace OpenAuth.Repository.Test
|
||||
serviceCollection.AddMemoryCache();
|
||||
serviceCollection.AddOptions();
|
||||
serviceCollection.AddScoped(typeof(IRepository<>), typeof(BaseRepository<>));
|
||||
serviceCollection.AddScoped(typeof(IUnitWork), typeof(UnitWork));
|
||||
|
||||
serviceCollection.AddDbContext<OpenAuthDBContext>(options =>
|
||||
options.UseSqlServer("Data Source=.;Initial Catalog=OpenAuthDB;User=sa;Password=000000;Integrated Security=True"));
|
||||
@@ -28,7 +33,6 @@ namespace OpenAuth.Repository.Test
|
||||
//注册repository层
|
||||
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());
|
||||
|
||||
// builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IRepository<>)).PropertiesAutowired();
|
||||
builder.Populate(serviceCollection);
|
||||
|
||||
var _container = builder.Build();
|
||||
|
||||
@@ -94,24 +94,24 @@ namespace OpenAuth.Repository.Test
|
||||
Id = id
|
||||
});
|
||||
|
||||
var user = repository.FindSingle(u => u.Id == id);
|
||||
var user = repository.FirstOrDefault(u => u.Id == id);
|
||||
Assert.NotNull(user);
|
||||
|
||||
//修改一个实体
|
||||
account = "newuser_" + DateTime.Now.ToString("yyyy_MM_dd HH:mm:ss");
|
||||
user.Account = account;
|
||||
repository.Update(user);
|
||||
var newuser = repository.FindSingle(u => u.Account == account);
|
||||
var newuser = repository.FirstOrDefault(u => u.Account == account);
|
||||
Assert.NotNull(newuser);
|
||||
|
||||
//批量修改
|
||||
repository.Update(u => u.Id == id, u =>new User{ Name = account});
|
||||
newuser = repository.FindSingle(u => u.Name == account);
|
||||
newuser = repository.FirstOrDefault(u => u.Name == account);
|
||||
Assert.NotNull(newuser);
|
||||
|
||||
//删除
|
||||
repository.Delete(u =>u.Id == id);
|
||||
newuser = repository.FindSingle(u => u.Id == id);
|
||||
newuser = repository.FirstOrDefault(u => u.Id == id);
|
||||
Assert.IsNull(newuser);
|
||||
}
|
||||
}
|
||||
|
||||
86
OpenAuth.Repository/Test/TestTransaction.cs
Normal file
86
OpenAuth.Repository/Test/TestTransaction.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
|
||||
namespace OpenAuth.Repository.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试事务
|
||||
/// </summary>
|
||||
class TestTransaction : TestBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 测试事务正常提交
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void NormalSubmit()
|
||||
{
|
||||
var unitWork = _autofacServiceProvider.GetService<IUnitWork>();
|
||||
unitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
var account = "user_" + DateTime.Now.ToString("yyyy_MM_dd HH:mm:ss");
|
||||
|
||||
AddAndUpdate(account, unitWork);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试事务回滚
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void SubmitWithRollback()
|
||||
{
|
||||
var unitWork = _autofacServiceProvider.GetService<IUnitWork>();
|
||||
var account = "user_" + DateTime.Now.ToString("yyyy_MM_dd HH:mm:ss");
|
||||
try
|
||||
{
|
||||
unitWork.ExecuteWithTransaction(() =>
|
||||
{
|
||||
AddAndUpdate(account, unitWork);
|
||||
|
||||
throw new Exception("模拟异常");
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
//如果没有插入成功,表示事务发生了回滚
|
||||
Assert.IsFalse(unitWork.Any<User>( u=>u.Id == account));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试添加,单个修改,Z.EntityFramework.Plus条件修改
|
||||
/// </summary>
|
||||
private void AddAndUpdate(string account, IUnitWork unitWork)
|
||||
{
|
||||
var user = new User
|
||||
{
|
||||
Id = account,
|
||||
Account = account,
|
||||
Name = account,
|
||||
};
|
||||
|
||||
unitWork.Add(user);
|
||||
|
||||
unitWork.Save();
|
||||
|
||||
|
||||
user.Account = "Trans_" + user.Account;
|
||||
user.Name = "Trans_" + user.Name;
|
||||
unitWork.Update(user);
|
||||
|
||||
unitWork.Save();
|
||||
|
||||
unitWork.Update<User>(u => u.Id == account, u => new User
|
||||
{
|
||||
Account = "Trans2_" + user.Account
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using OpenAuth.Repository.Core;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using Z.EntityFramework.Plus;
|
||||
@@ -18,6 +20,31 @@ namespace OpenAuth.Repository
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EF默认情况下,每调用一次SaveChanges()都会执行一个单独的事务
|
||||
/// 本接口实现在一个事务中可以多次执行SaveChanges()方法
|
||||
/// </summary>
|
||||
public void ExecuteWithTransaction(Action action)
|
||||
{
|
||||
using (IDbContextTransaction transaction = _context.Database.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
transaction.Commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回DbContext,用于多线程等极端情况
|
||||
/// </summary>
|
||||
public OpenAuthDBContext GetDbContext()
|
||||
{
|
||||
return _context;
|
||||
@@ -32,7 +59,7 @@ namespace OpenAuth.Repository
|
||||
return Filter(exp);
|
||||
}
|
||||
|
||||
public bool IsExist<T>(Expression<Func<T, bool>> exp) where T : class
|
||||
public bool Any<T>(Expression<Func<T, bool>> exp) where T : class
|
||||
{
|
||||
return _context.Set<T>().Any(exp);
|
||||
}
|
||||
@@ -40,7 +67,7 @@ namespace OpenAuth.Repository
|
||||
/// <summary>
|
||||
/// 查找单个
|
||||
/// </summary>
|
||||
public T FindSingle<T>(Expression<Func<T, bool>> exp) where T:class
|
||||
public T FirstOrDefault<T>(Expression<Func<T, bool>> exp) where T:class
|
||||
{
|
||||
return _context.Set<T>().AsNoTracking().FirstOrDefault(exp);
|
||||
}
|
||||
@@ -63,11 +90,14 @@ namespace OpenAuth.Repository
|
||||
/// <summary>
|
||||
/// 根据过滤条件获取记录数
|
||||
/// </summary>
|
||||
public int GetCount<T>(Expression<Func<T, bool>> exp = null) where T : class
|
||||
public int Count<T>(Expression<Func<T, bool>> exp = null) where T : class
|
||||
{
|
||||
return Filter(exp).Count();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增对象,如果Id为空,则会自动创建默认Id
|
||||
/// </summary>
|
||||
public void Add<T>(T entity) where T : BaseEntity
|
||||
{
|
||||
if (entity.KeyIsNull())
|
||||
@@ -78,9 +108,8 @@ namespace OpenAuth.Repository
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量添加
|
||||
/// 批量新增对象,如果对象Id为空,则会自动创建默认Id
|
||||
/// </summary>
|
||||
/// <param name="entities">The entities.</param>
|
||||
public void BatchAdd<T>(T[] entities) where T : BaseEntity
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
@@ -113,18 +142,23 @@ namespace OpenAuth.Repository
|
||||
|
||||
/// <summary>
|
||||
/// 实现按需要只更新部分更新
|
||||
/// <para>如:Update(u =>u.Id==1,u =>new User{Name="ok"});</para>
|
||||
/// <para>如:Update<User>(u =>u.Id==1,u =>new User{Name="ok"})</para>
|
||||
/// <para>该方法内部自动调用了SaveChanges(),需要ExecuteWithTransaction配合才能实现事务控制</para>
|
||||
/// </summary>
|
||||
/// <param name="where">The where.</param>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <param name="where">更新条件</param>
|
||||
/// <param name="entity">更新后的实体</param>
|
||||
public void Update<T>(Expression<Func<T, bool>> where, Expression<Func<T, T>> entity) where T:class
|
||||
{
|
||||
_context.Set<T>().Where(where).Update(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量删除
|
||||
/// <para>该方法内部自动调用了SaveChanges(),需要ExecuteWithTransaction配合才能实现事务控制</para>
|
||||
/// </summary>
|
||||
public virtual void Delete<T>(Expression<Func<T, bool>> exp) where T : class
|
||||
{
|
||||
_context.Set<T>().RemoveRange(Filter(exp));
|
||||
_context.Set<T>().Where(exp).Delete();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
@@ -178,5 +212,74 @@ namespace OpenAuth.Repository
|
||||
{
|
||||
return _context.Query<T>().FromSqlRaw(sql, parameters);
|
||||
}
|
||||
|
||||
#region 异步实现
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> ExecuteSqlRawAsync(string sql)
|
||||
{
|
||||
return await _context.Database.ExecuteSqlRawAsync(sql);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 异步保存
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public async Task<int> SaveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var entities = _context.ChangeTracker.Entries()
|
||||
.Where(e => e.State == EntityState.Added
|
||||
|| e.State == EntityState.Modified)
|
||||
.Select(e => e.Entity);
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var validationContext = new ValidationContext(entity);
|
||||
Validator.ValidateObject(entity, validationContext, validateAllProperties: true);
|
||||
}
|
||||
|
||||
return await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (ValidationException exc)
|
||||
{
|
||||
Console.WriteLine($"{nameof(Save)} validation exception: {exc?.Message}");
|
||||
throw (exc.InnerException as Exception ?? exc);
|
||||
}
|
||||
catch (Exception ex) //DbUpdateException
|
||||
{
|
||||
throw (ex.InnerException as Exception ?? ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据过滤条件获取记录数
|
||||
/// </summary>
|
||||
public async Task<int> CountAsync<T>(Expression<Func<T, bool>> exp = null) where T : class
|
||||
{
|
||||
return await Filter(exp).CountAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AnyAsync<T>(Expression<Func<T, bool>> exp) where T : class
|
||||
{
|
||||
return await _context.Set<T>().AnyAsync(exp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找单个,且不被上下文所跟踪
|
||||
/// </summary>
|
||||
public async Task<T> FirstOrDefaultAsync<T>(Expression<Func<T, bool>> exp) where T : class
|
||||
{
|
||||
return await _context.Set<T>().AsNoTracking().FirstOrDefaultAsync(exp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user