рдмрд╣реБ-рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ

рдмрд╣реБ-рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдореБрджреНрджрд╛ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдЙрдарддрд╛ рд╣реИред рдореБрдЦреНрдп рдкрд░рд┐рджреГрд╢реНрдп рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ:

  1. рдкреНрд░рдорд╛рдгрд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдкреНрд░рддрд┐рдмрдВрдз
  2. рдкреНрд░рдорд╛рдгреАрдХреГрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХрд╛ рдкреНрд░рддрд┐рдмрдВрдз, рд▓реЗрдХрд┐рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ
  3. рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпрдХреНрд╖ рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдирдзрд┐рдХреГрдд рдкрд╣реБрдБрдЪ рдХреЛ рд░реЛрдХрдиреЗ
  4. рдЦреЛрдЬ рдХреНрд╡реЗрд░реАрдЬрд╝ рдореЗрдВ рдбреЗрдЯрд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдирд╛ рдФрд░ UI рддрддреНрд╡реЛрдВ (рддрд╛рд▓рд┐рдХрд╛рдУрдВ, рд╕реВрдЪрд┐рдпреЛрдВ) рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдирд╛
  5. рдЕрдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд░реЛрдХрдирд╛

рдкрд░рд┐рджреГрд╢реНрдп 1-3 рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдлреНрд░реЗрдорд╡рд░реНрдХ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рднреВрдорд┐рдХрд╛-рдЖрдзрд╛рд░рд┐рдд рдпрд╛ рджрд╛рд╡рд╛-рдЖрдзрд╛рд░рд┐рдд рдкреНрд░рд╛рдзрд┐рдХрд░рдгред рд▓реЗрдХрд┐рди рдРрд╕реА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдЬрдм рдХреЛрдИ рдЕрдзрд┐рдХреГрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ "рдкрдбрд╝реЛрд╕реА" рдХреЗ рдбреЗрдЯрд╛ рддрдХ рд╕реАрдзреЗ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рд╣рд░ рд╕рдордп рдЕрдкрдиреЗ рдЦрд╛рддреЗ рдореЗрдВ рдХреЛрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЖрд╡рд╢реНрдпрдХ рдЪреЗрдХ рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк рдПрдХ рдХреЛрдб рд╕рдореАрдХреНрд╖рд╛ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рд╡реИрд╢реНрд╡рд┐рдХ рдбреЗрдЯрд╛ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдирд┐рдпрдореЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд░реЛрдХ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдЦ рдореЗрдВ рдЙрдирдХреА рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред

рд╕реВрдЪреА рдФрд░ рдЯреЗрдмрд▓


ASP.NET MVC рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рдпрдВрддреНрд░рдХ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

[HttpGet] public virtual IActionResult Get([FromQuery]T parameter) { var total = _dbContext .Set<TEntity>() .Where(/* some business rules */) .Count(); var items= _dbContext .Set<TEntity>() .Where(/* some business rules */) .ProjectTo<TDto>() .Skip(parameter.Skip) .Take(parameter.Take) .ToList(); return Ok(new {items, total}); } 

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдбреЗрдЯрд╛ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдХреА рд╕рд╛рд░реА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗрд╡рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рдкрд╛рд╕ рд░рд╣рддреА рд╣реИред рдХреНрдпрд╛ рд╡рд╣ рдпрд╛рдж рд░рдЦреЗрдЧрд╛ рдХрд┐ рд╢рд░реНрдд рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ Where рдпрд╛ рдирд╣реАрдВ?

рдЖрдк рд╡реИрд╢реНрд╡рд┐рдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХреНрд╕реЗрд╕ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП DbContext рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЛ рдЬрдЯрд┐рд▓ DbContext рд╣реЛрдЧрд╛ред

рдпрджрд┐ рдХрдИ рдирд┐рдпрдо рд╣реИрдВ, рддреЛ DbContext рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ "рдмрд╣реБрдд рдЕрдзрд┐рдХ" рд╕реАрдЦрдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдПрдХрдорд╛рддреНрд░ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░реЗрдЧрд╛ред

рдкрдл рд╡рд╛рд╕реНрддреБрдХрд▓рд╛


рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдБрдЪ рдФрд░ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХреА рд╕рдорд╕реНрдпрд╛рдПрдБ рдЙрддреНрдкрдиреНрди рд╣реБрдИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╣рдордиреЗ рдкрд░рддреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрди рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░ рджрд┐рдпрд╛ рдФрд░ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рд╕реЗ рд╣рдо рддреБрд░рдВрдд рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдкрд░рдд рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рддреЗ рд╣реБрдП рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рд▓реЗрдпрд░ рддрдХ рдкрд╣реБрдБрдЪ рдЧрдПред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рднреА " рдореЛрдЯреА рдЧреВрдВрдЧрд╛ рдмрджрд╕реВрд░рдд рдирд┐рдпрдВрддреНрд░рдХреЛрдВ " рдХрд░рд╛рд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА, рд╕реЗрд╡рд╛рдУрдВ рдФрд░ рд╡реНрдпрд╡рд╕рд╛рдп рддрд░реНрдХ рдХреЛ рд╕рдВрд░рдЪрд┐рдд рдХрд░рдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ рдкрд░ рд╕реНрдкрд░реНрд╢ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ред рдЧреНрд▓реЛрдмрд▓ рдлрд┐рд▓реНрдЯрд░ рдЗрд╕ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЖрдкрдХреЛ рдмрд╕ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдФрд░ рдкрд░рдд рд╕реЗ рдЕрдореВрд░реНрддрди рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЕрдореВрд░реНрдд рдЬреЛрдбрд╝реЗрдВ


.NET рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП IQueryable ред рдРрд╕реЗ рдкреНрд░рджрд╛рддрд╛ рддрдХ рдкрд╣реБрдБрдЪ рдХреЗ рд╕рд╛рде рдбрд╛рдпрд░реЗрдХреНрдЯ рдПрдХреНрд╕реЗрд╕ рдХреЛ DbContext рдмрджрд▓реЗрдВ:

  public interface IQueryableProvider { IQueryable<T> Query<T>() where T: class; IQueryable Query(Type type); } 

рдФрд░ рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдпрд╣ рдлрд╝рд┐рд▓реНрдЯрд░ рдмрдирд╛рдПрдВрдЧреЗ:

  public interface IPermissionFilter<T> { IQueryable<T> GetPermitted(IQueryable<T> queryable); } 

рд╣рдо рдкреНрд░рджрд╛рддрд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡рд╣ рд╕рднреА рдШреЛрд╖рд┐рдд рдлрд┐рд▓реНрдЯрд░ рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрдиреНрд╣реЗрдВ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ:

  public class QueryableProvider: IQueryableProvider { //       private static Type[] Filters = typeof(PermissionFilter<>) .Assembly .GetTypes() .Where(x => x.GetInterfaces().Any(y => y.IsGenericType && y.GetGenericTypeDefinition() == typeof(IPermissionFilter<>))) .ToArray(); private readonly DbContext _dbContext; private readonly IIdentity _identity; public QueryableProvider(DbContext dbContext, IIdentity identity) { _dbContext = dbContext; _identity = identity; } private static MethodInfo QueryMethod = typeof(QueryableProvider) .GetMethods() .First(x => x.Name == "Query" && x.IsGenericMethod); private IQueryable<T> Filter<T>(IQueryable<T> queryable) => Filters //     .Where(x => x.GetGenericArguments().First() == typeof(T)) //         Queryable<T> .Aggregate(queryable, (c, n) => ((dynamic)Activator.CreateInstance(n, _dbContext, _identity)).GetPermitted(queryable)); public IQueryable<T> Query<T>() where T : class => Filter(_dbContext.Set<T>()); //  EF Core  Set(Type type),    :( public IQueryable Query(Type type) => (IQueryable)QueryMethod .MakeGenericMethod(type) .Invoke(_dbContext, new object[]{}); } 

рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЗрд╖реНрдЯрддрдо рдирд╣реАрдВ рд╣реИред Activator.CreateInstance рдмрдЬрд╛рдп Activator.CreateInstance рд╕рдВрдХрд▓рд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреЗрдбрд╝реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдХреБрдЫ рдЖрдИрдУрд╕реА рдХрдВрдЯреЗрдирд░ рдЦреБрд▓реЗ рдЬреЗрдирд░рд┐рдХ рдХреЗ рдкрдВрдЬреАрдХрд░рдг рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рдЕрдиреБрдХреВрд▓рди рдкреНрд░рд╢реНрди рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред

рд╣рдо рдлрд┐рд▓реНрдЯрд░ рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ


рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддрд╛ рд╣реИ:

  public class EntityPermissionFilter: PermissionFilter<Entity> { public EntityPermissionFilter(DbContext dbContext, IIdentity identity) : base(dbContext, identity) { } public override IQueryable<Practice> GetPermitted( IQueryable<Practice> queryable) { return DbContext .Set<Practice>() .WhereIf(User.OrganizationType == OrganizationType.Client, x => x.Manager.OrganizationId == User.OrganizationId) .WhereIf(User.OrganizationType == OrganizationType.StaffingAgency, x => x.Partners .Select(y => y.OrganizationId) .Contains(User.OrganizationId)); } } 

рд╣рдо рдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЛрдб рдХреЛ рд╕рд╣реА рдХрд░рддреЗ рд╣реИрдВ


  [HttpGet] public virtual IActionResult Get([FromQuery]T parameter) { var total = QueryableProvider .Query<TEntity>() .Where(/* some business rules */) .Count(); var items = QueryableProvider .Query<TEntity>() .Where(/* some business rules */) .ProjectTo<TDto>() .Skip(parameter.Skip) .Take(parameter.Take) .ToList(); return Ok(new {items, total}); } 

рдмрд╣реБрдд рд╕рд╛рд░реЗ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВред рдпрд╣ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рд╕реЗ DbContext рддрдХ рд╕реАрдзреА рдкрд╣реБрдВрдЪ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП DbContext рд╣реБрдЖ рд╣реИ рдФрд░ рдпрджрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ, рддреЛ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдХреЗ рдореБрджреНрджреЗ рдХреЛ рдмрдВрдж рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдлрд┐рд▓реНрдЯрд░ рдХрд╛рдлреА рдЫреЛрдЯреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрди рд╕рдорд╛рди рдлрд┐рд▓реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ "рд╡рд┐рджреЗрд╢реА" рдбреЗрдЯрд╛ рддрдХ рдЕрдирдзрд┐рдХреГрдд рдкрд╣реБрдВрдЪ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИред рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред

Source: https://habr.com/ru/post/hi414897/


All Articles