
рдмрд╣реБ-рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдгрд╛рд▓рд┐рдпреЛрдВ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдореБрджреНрджрд╛ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдЙрдарддрд╛ рд╣реИред рдореБрдЦреНрдп рдкрд░рд┐рджреГрд╢реНрдп рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ:
- рдкреНрд░рдорд╛рдгрд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдкреНрд░рддрд┐рдмрдВрдз
- рдкреНрд░рдорд╛рдгреАрдХреГрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХрд╛ рдкреНрд░рддрд┐рдмрдВрдз, рд▓реЗрдХрд┐рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ
- рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпрдХреНрд╖ рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдирдзрд┐рдХреГрдд рдкрд╣реБрдБрдЪ рдХреЛ рд░реЛрдХрдиреЗ
- рдЦреЛрдЬ рдХреНрд╡реЗрд░реАрдЬрд╝ рдореЗрдВ рдбреЗрдЯрд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдирд╛ рдФрд░ UI рддрддреНрд╡реЛрдВ (рддрд╛рд▓рд┐рдХрд╛рдУрдВ, рд╕реВрдЪрд┐рдпреЛрдВ) рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдирд╛
- рдЕрдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд░реЛрдХрдирд╛
рдкрд░рд┐рджреГрд╢реНрдп 1-3 рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдлреНрд░реЗрдорд╡рд░реНрдХ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐
рднреВрдорд┐рдХрд╛-рдЖрдзрд╛рд░рд┐рдд рдпрд╛
рджрд╛рд╡рд╛-рдЖрдзрд╛рд░рд┐рдд рдкреНрд░рд╛рдзрд┐рдХрд░рдгред рд▓реЗрдХрд┐рди рдРрд╕реА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдЬрдм рдХреЛрдИ рдЕрдзрд┐рдХреГрдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ "рдкрдбрд╝реЛрд╕реА" рдХреЗ рдбреЗрдЯрд╛ рддрдХ рд╕реАрдзреЗ рдкрд╣реБрдВрдЪ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рд╣рд░ рд╕рдордп рдЕрдкрдиреЗ рдЦрд╛рддреЗ рдореЗрдВ рдХреЛрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЖрд╡рд╢реНрдпрдХ рдЪреЗрдХ рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк рдПрдХ рдХреЛрдб рд╕рдореАрдХреНрд╖рд╛ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рд╡реИрд╢реНрд╡рд┐рдХ рдбреЗрдЯрд╛ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдирд┐рдпрдореЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд░реЛрдХ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдЦ рдореЗрдВ рдЙрдирдХреА рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред
рд╕реВрдЪреА рдФрд░ рдЯреЗрдмрд▓
ASP.NET MVC рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд┐рдпрдВрддреНрд░рдХ рдХреБрдЫ
рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
[HttpGet] public virtual IActionResult Get([FromQuery]T parameter) { var total = _dbContext .Set<TEntity>() .Where() .Count(); var items= _dbContext .Set<TEntity>() .Where() .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 {
рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЗрд╖реНрдЯрддрдо рдирд╣реАрдВ рд╣реИред
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() .Count(); var items = QueryableProvider .Query<TEntity>() .Where() .ProjectTo<TDto>() .Skip(parameter.Skip) .Take(parameter.Take) .ToList(); return Ok(new {items, total}); }
рдмрд╣реБрдд рд╕рд╛рд░реЗ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВред рдпрд╣ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рд╕реЗ
DbContext
рддрдХ рд╕реАрдзреА рдкрд╣реБрдВрдЪ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
DbContext
рд╣реБрдЖ рд╣реИ рдФрд░ рдпрджрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ, рддреЛ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдХреЗ рдореБрджреНрджреЗ рдХреЛ рдмрдВрдж рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдлрд┐рд▓реНрдЯрд░ рдХрд╛рдлреА рдЫреЛрдЯреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрди рд╕рдорд╛рди рдлрд┐рд▓реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ "рд╡рд┐рджреЗрд╢реА" рдбреЗрдЯрд╛ рддрдХ рдЕрдирдзрд┐рдХреГрдд рдкрд╣реБрдВрдЪ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИред рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред