Asp.net core 一种始终使用实体框架核心筛选查询结果的方法
我在ASP.NET应用程序中的所有模型上使用Asp.net core 一种始终使用实体框架核心筛选查询结果的方法,asp.net-core,entity-framework-core,Asp.net Core,Entity Framework Core,我在ASP.NET应用程序中的所有模型上使用OrgID,使用EF作为数据库分区的方法。我这样做是为了让数据库可以在多个用户之间共享,同时确保只有他们组织的数据对他们可用 这迫使我在每次插入时编写这个OrgID,并过滤我对数据库的每次调用 例如,我查询当前用户的OrgID并将其插入控制器的Update方法中,如下所示: store.OrgID = await _userManager.GetUserAsync(User).OrgID; _context.Update(store); await _
OrgID
,使用EF作为数据库分区的方法。我这样做是为了让数据库可以在多个用户之间共享,同时确保只有他们组织的数据对他们可用
这迫使我在每次插入时编写这个OrgID
,并过滤我对数据库的每次调用
例如,我查询当前用户的OrgID
并将其插入控制器的Update
方法中,如下所示:
store.OrgID = await _userManager.GetUserAsync(User).OrgID;
_context.Update(store);
await _context.SaveChangesAsync();
然后,当我想列出对象时,我需要再次按OrgID
过滤:
var orgID = await _userManager.GetUserAsync(User).OrgID;
var stores = await _context.Stores.Where(s => s.OrgID == orgID).ToListAsync();
我很想找到一种方法来覆盖ApplicationDBContext
,以便自动处理这些内容,否则在每次调用数据库时总是处理这些内容是一项非常繁琐且容易出错的任务
任何建议都将不胜感激。在这种情况下,人们所做的是创建一个类来包装
DbContext
,并公开对其业务逻辑有意义的方法。在本例中,您可以创建一个UserRepository
/StoreRepository
类,其中搜索方法需要origID
参数
public class StoreRepository {
private ApplicationDBContext _context
StoreRepository(ApplicationDBContext context){
_context = context
}
public Task<Ilist<Store>> GetStores(int origID){
return _context.Stores.Where(s => s.OrgID == orgID).ToListAsync();
}
}
公共类存储库{
私有应用程序上下文\u上下文
StoreRepository(ApplicationDBContext上下文){
_上下文=上下文
}
公共任务GetStores(int-origID){
return _context.Stores.Where(s=>s.OrgID==OrgID.ToListAsync();
}
}
检查
全局查询筛选器是LINQ查询谓词(布尔表达式)
通常传递给应用于实体的LINQ Where查询运算符)
元数据模型中的类型(通常在OnModelCreating中)。这种过滤器
自动应用于涉及这些实体的任何LINQ查询
类型,包括间接引用的实体类型,例如通过
包含或直接导航属性引用的使用
创建具有OrgID的接口:
公共接口IOrgID
{
公共整数组织{get;set;}
}
所有型号都必须实现此接口,例如:
公共类应用程序用户:IdentityUser,IOrgID
{
公共整数组织{get;set;}
//...
}
公共类商店:IOrgID
{
公共整数组织{get;set;}
//...
}
使用通用存储库并根据当前登录用户的OrgID创建CRUD方法:
公共类MyRepo
{
私有只读应用程序的bContext\u上下文;
专用只读IHttpContextAccessor\u访问器;
私有只读int_orgID;
公共MyRepo(ApplicationDbContext上下文,IHTTPCContextAccessor访问器)
{
_上下文=上下文;
_存取器=存取器;
var userId=_accessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
_orgID=\u context.Users.Find(userId.orgID);
}
公共异步任务GetAsync(表达式whereExp)
其中T:class,IOrgId
{
返回wait _context.Set().Where(x=>x.OrgId==_OrgId).FirstOrDefaultAsync(whereExp);
}
公共异步任务创建(T实体)
其中T:class,IOrgId
{
_context.Set().Add(entitiy);
return wait_context.SaveChangesAsync()>0;
}
公共异步任务UpdateAsync(T实体)
其中T:class,IOrgId
{
_context.Entry(entity.State=EntityState.Modified;
return wait_context.SaveChangesAsync()>0;
}
公共异步任务ListAsync(表达式whereExp)
其中T:class,IOrgId
{
返回wait _context.Set().AsNoTracking().Where(x=>x.OrgId==\u OrgId.Where(whereExp.ToListAsync();
}
公共异步任务DeleteAync(T实体)
其中T:class,IOrgId
{
_context.Entry(entity).State=EntityState.Deleted;
return wait_context.SaveChangesAsync()>0;
}
}
调用ToListSync()
将导致性能问题,因为它将执行查询并返回数据集实体的完整列表。另一种方法是返回IQueryable
并删除。ToListSync()
,因此,该方法将返回一个查询而不是实体。有趣的是,这表明许多应用程序访问相同的数据库,因为您必须在startup ConfigureService方法中指定TenantID(在我的例子中是OrgID)。我使用的是一种不同的租赁模式,我在应用程序级别也有多个租户。仍然解决了我对软删除的另一个要求。