{"id":371027,"date":"2024-05-21T04:38:53","date_gmt":"2024-05-21T04:38:53","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=371027"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=371027","title":{"rendered":"<span>\u0411\u043b\u0435\u0441\u043a \u0438 \u043d\u0438\u0449\u0435\u0442\u0430 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u00ab\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u00bb \u0432 \u0421#. \u041e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u043c \u043f\u043b\u0430\u043d\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041e \u0447\u0451\u043c \u0441\u0442\u0430\u0442\u044c\u044f?\u00a0<\/h3>\n<p>\u041e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 \u00ab\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c, \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043c \u043a\u043e\u0434\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 &#8212; \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u0447\u043d\u043e. \u041f\u043e\u0447\u0435\u043c\u0443? &#8212; \u0447\u0438\u0442\u0430\u0435\u043c \u043d\u0438\u0436\u0435.\u00a0<\/p>\n<h3>\u042d\u0442\u043e\u0433\u043e \u043c\u0430\u043b\u043e, \u0447\u0442\u043e \u0435\u0449\u0451?\u00a0<\/h3>\n<p>\u041a \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 Web API \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0430\u043d\u0435\u043c\u0438\u0447\u043d\u043e\u0439 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 MediatR, Postgres \u0438 Docker Compose. \u0412\u0441\u0451, \u043a\u0430\u043a \u0412\u044b \u043b\u044e\u0431\u0438\u0442\u0435 \u0438, \u0442\u0430\u043a\u0438 \u0434\u0430, \u0430\u043d\u0435\u043c\u0438\u0447\u043d\u043e\u0439 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u043c\u044b \u043d\u0430\u0440\u0443\u0448\u0438\u043c \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044e, \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0438\u043a\u0443\u0434\u0430.\u00a0<\/p>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043b\u0430\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f SQL &#8212; \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 EF\u00a0 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437 \u043d\u0438\u0445 (\u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c).<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430: <a href=\"https:\/\/github.com\/potandr1977\/SpecificationPatternPoC\"><u>\u0442\u0443\u0442<\/u><\/a><\/p>\n<h3>\u041f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/h3>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u0435\u0440\u0435\u0432\u043e\u0437\u043a\u0443 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u0430\u0432\u0438\u0430\u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043e\u043c. \u0411\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u043d\u0430 \u0435\u0451 \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<h3>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439<\/h3>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 \u043d\u0430\u0441 \u0432\u0438\u0434\u0435\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0440\u0435\u0439\u0441\u0430\u0445 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432:<\/p>\n<pre><code class=\"cs\">\/\/ \u041c\u0435\u0442\u043e\u0434 \u043d\u0430 Over9000 \u0441\u0442\u0440\u043e\u043a. public async Task&lt;List&lt;\u043a\u0430\u043a\u0430\u044f\u0442\u043e\u041c\u043e\u0434\u0435\u043b\u044c>> GetPessengersFlightNoAsync(\u043a\u0430\u043a\u043e\u0439\u0442\u043e\u0417\u0430\u043f\u0440\u043e\u0441) {     var query = from smth1  in \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442.Something1                   join smth2 in \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442.Something2                   \u2026..                   join smth20 in \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442.Something20                   where \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f                   select new \/\/ \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0442\u0438\u043f                   {                        Field1,                       \u2026                       Field30                   };      if (request.Field1 != null)     {         query = query.Where( x => \u0443\u0441\u043b\u043e\u0432\u0438\u0435_\u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0435\u0435_\u043e\u0442_\u043f\u043e\u043b\u0435\u0439_\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u04301);     }     \u2026     if (request.Field15 != null)     {         query = query.Where( x => \u0443\u0441\u043b\u043e\u0432\u0438\u0435_\u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0435\u0435_\u043e\u0442_\u043f\u043e\u043b\u0435\u0439_\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u043015);     }     var anonimousModels = await query.ToListAsync();      return anonimousModels.To\u041a\u0430\u043a\u0438\u0435\u0442\u043e\u0422\u043e\u041c\u043e\u0434\u0435\u043b\u0438(): }<\/code><\/pre>\n<p>\u0412 \u0447\u0451\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430? \u041e\u043d \u043e\u0433\u0440\u043e\u043c\u0435\u043d \u0438 \u0435\u0433\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0432 \u043d\u0430\u0431\u043e\u0440 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 select \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0442\u0438\u043f.\u00a0<\/p>\n<p>C# \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0441 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u043e\u0442 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c.\u00a0<\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b &#8212; \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0443\u0441\u043f\u0435\u0445, \u043d\u043e \u0442\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432\u044b\u0440\u0430\u0441\u0442\u0435\u0442 \u043a\u0430\u043a \u043f\u043e\u043f\u043a\u043e\u0440\u043d \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0433\u0440\u0435\u0432\u0430, \u0430 \u043e\u043d\u043e \u043d\u0430\u043c \u043d\u0430\u0434\u043e? &#8212; \u043d\u0435\u0442!<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 select, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0432 \u0432\u0438\u0434\u0435 \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u0440\u0442\u0435\u0436.Item1, \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0442 \u0447\u0443\u0432\u0441\u0442\u0432\u0443 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e\u0433\u043e \u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u043a \u043d\u044d\u0439\u043c\u0438\u043d\u0433\u0443.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0437\u0430\u0442\u0440\u0443\u0434\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<h3>\u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435<\/h3>\n<p>\u0415\u0441\u0442\u044c \u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0435\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a, \u0447\u0435\u043c \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u043e\u0433\u043e \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 Domain Driven Design \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u0437\u0430\u0449\u0438\u0442\u0430 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438 \u043e\u0442 \u043f\u0435\u0440\u0435\u0442\u0435\u043a\u0430\u043d\u0438\u044f \u043d\u0430 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u044e. \u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043e\u0442\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u043e\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0443 \u043d\u0430\u0441 \u2026 \u043d\u0430 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438, \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044d\u0442\u043e \u043a\u043e\u0440\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0431\u0435\u0434.<\/p>\n<p>\u041a\u0430\u043a \u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445? \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f37\/a42\/7a6\/f37a427a6ab249e02ab3a70816f90c6f.png\" width=\"148\" height=\"529\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f37\/a42\/7a6\/f37a427a6ab249e02ab3a70816f90c6f.png\"\/><\/figure>\n<p>\u0418, \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u043e\u0441\u0430\u0434\u043a\u0438 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u0432 \u0441\u0430\u043c\u043e\u043b\u0451\u0442\u0435, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443, \u0430 \u0435\u0441\u043b\u0438 N-\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 N \u0446\u0435\u043f\u043e\u0447\u0435\u043a.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fbc\/a55\/d39\/fbca55d390d41fb508a7e2cce2816275.png\" width=\"455\" height=\"513\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fbc\/a55\/d39\/fbca55d390d41fb508a7e2cce2816275.png\"\/><\/figure>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c 90% \u043a\u043e\u0434\u0430 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439, \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044f \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c join-\u043e\u0432 \u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c if-\u043e\u0432, \u0442.\u043a. \u043a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0430\u0451\u0442\u0441\u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0443.<\/p>\n<h3>\u041f\u0430\u0442\u0442\u0435\u0440\u043d &#171;\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f&#187;. \u0411\u043b\u0435\u0441\u043a<\/h3>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441 N \u0434\u043e 1 \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0445 \u0440\u0435\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u00a0 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u201c\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u201d, \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0432 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/07c\/2bf\/32c\/07c2bf32c8a3d5dc57fa3229f6b16a33.png\" width=\"455\" height=\"589\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/07c\/2bf\/32c\/07c2bf32c8a3d5dc57fa3229f6b16a33.png\"\/><\/figure>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0430 \u043e\u0434\u0438\u043d DbSet \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0432 DbContext, \u0442.\u0435. \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 100 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u201cGetPassenger\u0427\u0442\u043e\u0422\u043e\u0422\u0430\u043c\u201d \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 PassengerController, \u0442\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b 1 \u043c\u0435\u0442\u043e\u0434\u043e\u043c GetPassengers,<\/p>\n<p>\u043d\u0443 \u0438\u043b\u0438 GetPassengersWithSpecifications, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9f4\/202\/dfd\/9f4202dfd56bb4615f502829b339e06f.png\" width=\"700\" height=\"410\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9f4\/202\/dfd\/9f4202dfd56bb4615f502829b339e06f.png\"\/><\/figure>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043e\u0442\u0431\u043e\u0440\u0430 \u00ab\u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442\u00bb \u043d\u0430\u00a0\u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0434\u043e\u043c\u0435\u043d\u0430, \u0447\u0442\u043e\u00a0\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0432\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0411\u0414 \u043d\u0430\u00a0\u0434\u0440\u0443\u0433\u0443\u044e. Postgres \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430\u00a0MongoDb \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u00a0\u0434\u043e\u043c\u0435\u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0435\u00a0\u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f, \u0442.\u043a. \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 Expression, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043a\u0430\u043a \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 EF \u0442\u0430\u043a \u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 MongoDbDriver.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cf8\/8dd\/0d3\/cf88dd0d3799e0b6c7584b5147e07184.png\" width=\"384\" height=\"371\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cf8\/8dd\/0d3\/cf88dd0d3799e0b6c7584b5147e07184.png\"\/><\/figure>\n<p>\u0418\u0442\u0430\u043a, \u0432 DbContext\u00a0 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0432 \u043d\u0430\u0448 \u0434\u043e\u043c\u0435\u043d.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 4 \u0444\u0430\u0439\u043b\u0430:\u00a0<\/p>\n<p>Specification.cs &#8212; \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0433\u0434\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u0438, \u0434\u0438\u0437\u044a\u044e\u043d\u043a\u0446\u0438\u0438 \u0438 \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0436\u0435\u043b\u0430\u043d\u0438\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439. \/\/\/ &lt;\/summary> public abstract class Specification&lt;T> {     \/\/ \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448\u0443 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 Expression.     public abstract Expression&lt;Func&lt;T, bool>> ToExpression();      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u0448\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043d\u0430 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u044c.     public virtual bool IsSatisfiedBy(T entity)     {         Func&lt;T, bool> predicate = ToExpression().Compile();         return predicate(entity);     }      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u0438, \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\" \u043d\u0430\u0434 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438.     \/\/\/ \u041d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.     \/\/\/ \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public Specification&lt;T> And(Specification&lt;T> specification) =>         new AndSpecification&lt;T>(this, specification);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0438\u0437\u044a\u044e\u043d\u043a\u0446\u0438\u0438, \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\u041b\u0418\" \u043d\u0430\u0434 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438.      \/\/\/ \u041d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.     \/\/\/ \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public Specification&lt;T> Or(Specification&lt;T> specification) =>         new OrSpecification&lt;T>(this, specification);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u044f.     \/\/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;returns>&lt;\/returns>     public Specification&lt;T> Not() => new NotSpecification&lt;T>(this);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c false \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static bool operator false (Specification&lt;T> specification) => false;      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c true \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static bool operator true(Specification&lt;T> specification) => true;      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\".     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"left\">&lt;\/param>     \/\/\/ &lt;param name=\"right\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static Specification&lt;T> operator &amp;(Specification&lt;T> left, Specification&lt;T> right) =>         left.And(right);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\u041b\u0418\".     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"left\">&lt;\/param>     \/\/\/ &lt;param name=\"right\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static Specification&lt;T> operator |(Specification&lt;T> left, Specification&lt;T> right) =>         left.Or(right);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u044f.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"left\">&lt;\/param>     \/\/\/ &lt;param name=\"right\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static Specification&lt;T> operator !(Specification&lt;T> specification) => specification.Not(); } <\/code><\/pre>\n<p>AndSpecification.cs &#8212; \u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u0438 \u0434\u0432\u0443\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u0442.\u0435. \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c VasyaAndPetia =\u00a0 Vasya &amp; Petia.<\/p>\n<p>OrSpecification.cs &#8212; \u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0434\u0438\u0437\u044a\u044e\u043d\u043a\u0446\u0438\u0438 \u0434\u0432\u0443\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u0442.\u0435. \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c VasyaAndPetia =\u00a0 Vasya | Petia.<\/p>\n<p>NotSpecification.cs &#8212; \u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0438\u0441\u0430\u0442\u044c NotVasya = !Vasya.<\/p>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c AndSpecification, OrSpecification \u0438 NotSpecification \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b AndAlso, OrElse \u0438 Not \u043a\u043b\u0430\u0441\u0441\u0430 Expression \u0438 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0434\u0435\u0442\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0442\u044f\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0439\u0441\u043e\u043c \u0432 \u0430\u044d\u0440\u043e\u043f\u043e\u0440\u0442 \u041b\u043e\u0441-\u0410\u043d\u0434\u0436\u0435\u043b\u0435\u0441\u0430 \u043f\u043e \u0431\u0438\u043b\u0435\u0442\u0430\u043c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 $300, \u0442\u043e \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:\u00a0<\/p>\n<pre><code>var laKidsHigher300 = AgeUnder18Spec &amp; ArrivalAirportLASpec &amp; !PriceUnder300Spec;<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043e\u0442\u0431\u043e\u0440\u0430, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0432 \u043e\u0431\u044a\u0435\u043c \u043a\u043e\u0434\u0430. \u041c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430 &#8212; \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u0435\u0440\u043d\u0435\u0435, \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c. \u0413\u0434\u0435 \u043e\u043d\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043a\u0440\u0438\u043d:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/564\/78f\/cd9\/56478fcd93fb6cb81d3f07f34bc40aa1.png\" width=\"315\" height=\"423\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/564\/78f\/cd9\/56478fcd93fb6cb81d3f07f34bc40aa1.png\"\/><\/figure>\n<p>\u041d\u0430 \u0431\u0430\u0437\u0435 Specification.cs \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u043f\u043e \u0438\u0445 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c.\u00a0<\/p>\n<p>PassengerIdsSpecification.cs<\/p>\n<pre><code>\/\/\/ &lt;summary> \/\/\/ \u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u0430 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \/\/\/ &lt;\/summary> \/\/\/ &lt;param name=\"passnegerIds\">\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432.&lt;\/param> public class PassengerIdsSpecification&lt;T>(int[] passnegerIds) : Specification&lt;T>     where T : IFiltrationFieldsSet {     private readonly int[] passengerIds = passnegerIds;      public override Expression&lt;Func&lt;T, bool>> ToExpression() =>         p => passengerIds.Contains(p.Id); }<\/code><\/pre>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044d\u0442\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0434\u0430\u0442\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u0435 (UpdateTs) \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b. \/\/\/ &lt;\/summary public class UpdateTsIntervalSpecification&lt;T>(DateTime? updateTsStrart, DateTime? updateTsEnd) : Specification&lt;T>     where T : IFiltrationFieldsSet {     private readonly DateTime? updateTsStart = updateTsStrart;     private readonly DateTime? updateTsEnd = updateTsEnd;      public override Expression&lt;Func&lt;T, bool>> ToExpression()     {         if (updateTsStart.HasValue &amp;&amp; !updateTsEnd.HasValue)         {             var dateFrom = GetStartDate(updateTsStart.Value);              return x => x.UpdateTs >= dateFrom || x.UpdateTs == null;         }          if (updateTsEnd.HasValue &amp;&amp; !updateTsStart.HasValue)         {             var dateTo = GetEndDate(updateTsEnd.Value);              return x => x.UpdateTs &lt; dateTo || x.UpdateTs == null;         }          if (updateTsEnd.HasValue &amp;&amp; updateTsStart.HasValue)         {             var dateFrom = GetStartDate(updateTsStart.Value);             var dateTo = GetEndDate(updateTsEnd.Value);              return x =>                 (x.UpdateTs >= dateFrom &amp;&amp; x.UpdateTs &lt; dateTo) || x.UpdateTs == null;         }          return x => true;     }      private static DateTime GetStartDate(DateTime requestTo) => requestTo.Date;      private static DateTime GetEndDate(DateTime requestFrom) => requestFrom.Date.AddDays(1); }  <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0434\u0430\u0442\u0430\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u0430\u0445<\/p>\n<p>IFiltrationFieldsSet &#8212; \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u043f\u043e\u043b\u044f, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c, \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u043f\u043e\u0437\u0436\u0435, \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0435\u0433\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u043e\u043c Passenger, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043e\u0442 IFiltrationFieldsSet , \u0442.\u0435. \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>public class UpdateTsIntervalSpecification&lt;T>(DateTime? updateTsStrart, DateTime? updateTsEnd) : Specification&lt;T>     where T : Passenger <\/code><\/pre>\n<h3>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u0433\u043e\u0442\u043e\u0432\u044b, \u043c\u043e\u0436\u043d\u043e \u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c<\/h3>\n<p>\u0412 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u041b\u0435\u0433\u0435\u043d\u0434\u0430 \u0442\u0430\u043a\u0430\u044f: \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 PassengerIds, \u043d\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 PassengerIdsToExclude \u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0434\u0435\u043d\u044c. \u041f\u0440\u0438\u0447\u0451\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, PassengerIdsToExclude \u0438 \u043e\u0442\u0431\u043e\u0440 \u043f\u043e \u0434\u0430\u0442\u0430\u043c &#8212; \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \/\/\/ &lt;\/summary> \/\/\/ &lt;param name=\"request\">&lt;\/param> \/\/\/ &lt;returns>&lt;\/returns> private static Specification&lt;T> ConstructSpecification&lt;T>(GetPassengerRequest request)     where T : IFiltrationFieldsSet {     \/\/ \u0412\u044b\u0431\u043e\u0440\u043a\u0430 \u043f\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.     var filter = (Specification&lt;T>) new PassengerIdsSpecification&lt;T>(request.PassengerIds);      if (request.PassengerIdsToExclude != null)     {         \/\/ \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u043d\u044b \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044e \u0438\u0437 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445,         \/\/ \u0442\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043f\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0432 \u0435\u0451, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \"!\".         filter &amp;= !(new PassengerIdsSpecification&lt;T>(request.PassengerIdsToExclude));     }      if (request.UpdateTsStart.HasValue || request.UpdateTsEnd.HasValue)     {         \/\/ \u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u043d\u044b \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430, \u0442\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u043c \u043f\u043e \u0434\u0430\u0442\u0430\u043c.         filter &amp;= new UpdateTsIntervalSpecification&lt;T>(request.UpdateTsStart, request.UpdateTsEnd);     }      return filter; } <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0440\u0435\u0439\u0441\u0430\u0445 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043d\u043e\u043c\u0435\u0440\u0430\u0445 \u0440\u0435\u0439\u0441\u043e\u0432 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432. \/\/\/ &lt;\/summary> \/\/\/ &lt;param name=\"request\">&lt;\/param> \/\/\/ &lt;returns>&lt;\/returns> public Task&lt;IReadOnlyCollection&lt;PassengerFlightNumModel>> GetPessengersFlightNoAsync(GetPassengerRequest request) {     \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.     var filter = ConstructSpecification&lt;Passenger>(request);      \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. EF \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u0435\u0439 \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.     \/\/ \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u0435\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 EF \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441.     return _passengerSpecificationProvider.GetPassengersWithSpecificationsAsync(         filter.ToExpression(),         p => new PassengerFlightNumModel         {             Id = p.Id,             FirstName = p.FirstName,             LastName = p.LastName,             FlightNum = p.Booking.BookingLegals.FirstOrDefault().Flight.FlightNo         }); } <\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430\u0445 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043d\u043e\u043c\u0435\u0440\u0430\u0445 \u043c\u0435\u0441\u0442 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432. \/\/\/ &lt;\/summary> \/\/\/ &lt;param name=\"request\">&lt;\/param> \/\/\/ &lt;returns>&lt;\/returns> public Task&lt;IReadOnlyCollection&lt;PassengerPhoneModel>> GetPessengersPhoneAsync(GetPassengerRequest request) {     \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.     var filter = ConstructSpecification&lt;Passenger>(request);      return _passengerSpecificationProvider.GetPassengersWithSpecificationsAsync(         filter.ToExpression(),         p => new PassengerPhoneModel         {             Id = p.Id,             FirstName = p.FirstName,             LastName = p.LastName,             PhoneNumber = p.Account.Phones.FirstOrDefault(x => x.PrimaryPhone).PhoneValue,         }); } <\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u043e EF \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u0411\u0414, \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\u043c\u0438 (join) \u0442\u0430\u0431\u043b\u0438\u0446 \u0411\u0414. \u0414\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 GetPessengersFlightNoAsync EF \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 SQL &#8212; \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"cs\"> SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", (             SELECT f.flight_no             FROM postgres_air.booking_leg AS b0             LEFT JOIN postgres_air.flight AS f ON b0.flight_id = f.flight_id              WHERE b.booking_id IS NOT NULL AND b.booking_id = b0.booking_id              LIMIT 1) AS \"FlightNum\"          FROM postgres_air.passenger AS p          LEFT JOIN postgres_air.booking AS b ON p.booking_id = b.booking_id          WHERE p.passenger_id = ANY(@__passengerIds_0) AND NOT(p.passenger_id = ANY(@__passengerIds_1) AND p.passenger_id = ANY(@__passengerIds_1) IS NOT NULL) <\/code><\/pre>\n<p>\u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 GetPessengersPhoneAsync \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"cs\">SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", (                         SELECT p0.phone                         FROM postgres_air.phone AS p0                         WHERE a.account_id IS NOT NULL AND a.account_id = p0.account_id AND p0.primary_phone                         LIMIT 1) AS \"PhoneNumber\"         FROM postgres_air.passenger AS p         LEFT JOIN postgres_air.account AS a ON p.account_id = a.account_id         WHERE p.passenger_id = ANY(@__passengerIds_0) AND NOT(p.passenger_id = ANY(@__passengerIds_1) AND p.passenger_id = ANY(@__passengerIds_1) IS NOT NULL) AND(p.update_ts &lt; @__dateTo_2 OR p.update_ts IS NULL) <\/code><\/pre>\n<p>\u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 GetPessengersSeatAsync \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"cs\"> SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", (             SELECT b.seat             FROM postgres_air.boarding_pass AS b             WHERE p.passenger_id = b.passenger_id              LIMIT 1) AS \"BoardingPassSeat\"          FROM postgres_air.passenger AS p          WHERE p.passenger_id = ANY(@__passengerIds_0) AND NOT(p.passenger_id = ANY(@__passengerIds_1) AND p.passenger_id = ANY(@__passengerIds_1) IS NOT NULL) AND(p.update_ts &lt; @__dateTo_2 OR p.update_ts IS NULL)  <\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434 join-\u044b, if-\u044b \u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c. Join-\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u0432 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044f\u0445 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, if-\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u0445. \u0411\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0434\u043e\u043c\u0435\u043d\u0430.\u00a0<\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0432\u0441\u0451 \u043e\u043a, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435\u00a0 &#8212; \u043d\u0435\u0442.\u00a0<\/p>\n<h3>\u041e\u0446\u0435\u043d\u0438\u043c SQL. \u041d\u0438\u0449\u0435\u0442\u0430<\/h3>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u043c \u043a \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043a\u043b\u0430\u0441\u0441\u0435 PassengerNoSpecificationProvider.cs \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 PassengerSpecificationProvider.cs. \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u043e\u0439 SQL \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 EF \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 GetPessengersFlightNoAsync \u0432 \u043e\u0431\u043e\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u0430\u0445.<\/p>\n<p>SQL \u0431\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cs\"> SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", f.flight_no AS \"FlightNum\"          FROM postgres_air.passenger AS p          LEFT JOIN postgres_air.booking AS b ON p.booking_id = b.booking_id          LEFT JOIN postgres_air.flight AS f ON(              SELECT b0.flight_id              FROM postgres_air.booking_leg AS b0              WHERE b0.booking_id = b.booking_id              LIMIT 1) = f.flight_id          WHERE p.passenger_id = ANY(@__request_PassengerIds_0)          AND NOT(p.passenger_id = ANY(@__request_PassengerIdsToExclude_1)          AND p.passenger_id = ANY(@__request_PassengerIdsToExclude_1) IS NOT NULL)  \u043f\u043b\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0430:         \"QUERY PLAN\"         \"Hash Left Join  (cost=26608.37..36174.63 rows=5 width=20)\"         \"  Hash Cond: ((SubPlan 1) = f.flight_id)\"         \"  ->  Nested Loop Left Join  (cost=0.87..64.54 rows=5 width=24)\"         \"        ->  Index Scan using passenger_pkey on passenger p  (cost=0.43..42.29 rows=5 width=20)\"         \"              Index Cond: (passenger_id = ANY ('{1,2,3,4,5}'::integer[]))\"         \"              Filter: ((passenger_id &lt;> ALL ('{2,3}'::integer[])) OR ((passenger_id = ANY ('{2,3}'::integer[])) IS NULL))\"         \"        ->  Index Only Scan using booking_pkey on booking b  (cost=0.43..4.45 rows=1 width=8)\"         \"              Index Cond: (booking_id = p.booking_id)\"         \"  ->  Hash  (cost=15398.78..15398.78 rows=683178 width=8)\"         \"        ->  Seq Scan on flight f  (cost=0.00..15398.78 rows=683178 width=8)\"         \"  SubPlan 1\"         \"    ->  Limit  (cost=0.00..27326.28 rows=1 width=4)\"         \"          ->  Seq Scan on booking_leg b0  (cost=0.00..355241.70 rows=13 width=4)\"         \"                Filter: (booking_id = b.booking_id)\"     <\/code><\/pre>\n<p>SQL \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cs\"> SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", (             SELECT f.flight_no             FROM postgres_air.booking_leg AS b0             LEFT JOIN postgres_air.flight AS f ON b0.flight_id = f.flight_id              WHERE b.booking_id IS NOT NULL AND b.booking_id = b0.booking_id              LIMIT 1) AS \"FlightNum\"          FROM postgres_air.passenger AS p          LEFT JOIN postgres_air.booking AS b ON p.booking_id = b.booking_id          WHERE p.passenger_id = ANY(@__passengerIds_0) AND NOT(p.passenger_id = ANY(@__passengerIds_1) AND p.passenger_id = ANY(@__passengerIds_1) IS NOT NULL)  \u043f\u043b\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0430:         \"QUERY PLAN\"         \"Nested Loop  (cost=0.87..136740.13 rows=5 width=48)\"         \"  ->  Index Scan using passenger_pkey on passenger p  (cost=0.43..42.29 rows=5 width=20)\"         \"        Index Cond: (passenger_id = ANY ('{1,2,3,4,5}'::integer[]))\"         \"        Filter: ((passenger_id &lt;> ALL ('{2,3}'::integer[])) OR ((passenger_id = ANY ('{2,3}'::integer[])) IS NULL))\"         \"  ->  Index Only Scan using booking_pkey on booking b  (cost=0.43..4.45 rows=1 width=8)\"         \"        Index Cond: (booking_id = p.booking_id)\"         \"  SubPlan 1\"         \"    ->  Limit  (cost=0.42..27335.12 rows=1 width=4)\"         \"          ->  Nested Loop Left Join  (cost=0.42..355351.45 rows=13 width=4)\"         \"                ->  Seq Scan on booking_leg b0  (cost=0.00..355241.70 rows=13 width=4)\"         \"                      Filter: (b.booking_id = booking_id)\"         \"                ->  Index Scan using flight_pkey on flight f  (cost=0.42..8.44 rows=1 width=8)\"         \"                      Index Cond: (flight_id = b0.flight_id)\"  <\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, SQL \u0431\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u0435\u043d. \u041e\u043d \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u0435\u0435 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0440\u0443\u043a\u0430\u043c\u0438 \u043d\u0430\u043c\u0435\u043a\u043d\u0443\u043b\u0438 EF \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0442\u0430\u043a\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430, \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e EF \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u043f\u043e\u043b\u043d\u0435 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 SQL \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0438 \u0441\u0432\u044f\u0437\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0411\u0414, \u043d\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u044d\u0442\u043e \u043f\u043e\u0432\u043e\u0434 \u0437\u0430\u0434\u0443\u043c\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e.\u00a0<\/p>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0431\u0430\u0437\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b \u0432 \u043f\u043b\u0430\u043d\u0435 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043c\u0430 \u043a\u043e\u0434\u0430, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b \u0432 \u043f\u043b\u0430\u043d\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a SQL \u0441\u0435\u0440\u0432\u0435\u0440\u0443.<\/p>\n<h3>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439. \u0412\u0441\u0442\u0430\u0451\u043c \u0441 \u043a\u043e\u043b\u0435\u043d<\/h3>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043e\u0437\u0432\u0443\u0447\u0443 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u0443\u044e \u0438\u0434\u0435\u044e, \u043d\u043e \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043d\u0430\u0431\u043e\u0440\u0430\u043c\u0438 join-\u043e\u0432. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 join-\u044b , \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439. EF \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u0435\u0433\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 SQL, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 join-\u044b. EF \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430 \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u044f, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 select, \u0432\u043e\u0432\u0441\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0432\u0441\u0435\u0445 \u0442\u0435\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0435\u043c\u0443 \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0432 linq &#8212; \u0437\u0430\u043f\u0440\u043e\u0441\u0435.\u00a0<\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043c\u044b \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0435\u043c \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043b\u0438\u0448\u043d\u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\u0445, \u043d\u043e \u0434\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0442\u043e\u0440 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 Postgres \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u043b\u0438\u0448\u043d\u0438\u0435 join-\u044b \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432 select-\u0435. \u042d\u0442\u043e \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044e\u0442 \u043f\u043b\u0430\u043d\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u041f\u043b\u0430\u043d\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432\u0441\u0451 \u044d\u0442\u043e \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043c\u044b \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432\u00a0linq\u2011\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445, \u0432\u00a0\u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0432\u043e\u0434\u0438\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u0445 \u0432\u00a0\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u0445. <\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u00ab\u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435\u00bb?\u00a0\u2014 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u00a0\u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0435\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u00a0\u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u0435\u0442\u043e\u0434\u0430, \u043d\u043e\u00a0\u0438 \u043f\u043e\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f\u00a0\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u0432\u00a0\u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430\u00a0\u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0448\u0435\u00a0\u2014 \u043d\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e. <\/p>\n<p>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 IFiltrationFieldsSet &#8212; \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u043f\u043e\u043b\u044f, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430\u0448\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u044f \u0432\u0432\u0451\u043b \u0435\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u0430\u043a \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0442\u0430\u043a \u0438 \u0441 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u043c\u0438 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438, \u043d\u0435 \u043c\u0435\u043d\u044f\u044f \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0435\u0432 \u043e\u0442\u0431\u043e\u0440\u0430, \u0442.\u0435. \u044d\u0442\u043e \u0447\u0438\u0441\u0442\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public async Task&lt;IReadOnlyCollection&lt;T>> GetPassengersWithSpecificationsRawAsync&lt;T>(     Expression&lt;Func&lt;PassengerRawModel, bool>> filter,     Expression&lt;Func&lt;PassengerRawModel, T>> selector) {     var query = from ps in airContext.Passengers                  \/\/ FlightNum                 join bkngs in airContext.Bookings                 on ps.BookingId equals bkngs.Id into bookings                 from bk in bookings.DefaultIfEmpty()                  let bl = airContext.BookingLegals                     .Where(x => x.BookingId.Equals(bk.Id))                     .FirstOrDefault()                  join flts in airContext.Flights                   on bl.FlightId equals flts.Id into flights                 from fl in flights.DefaultIfEmpty()                  \/\/ PhoneNumber                 join accs in airContext.Accounts                 on ps.AccountId equals accs.Id into accounts                 from acc in accounts.DefaultIfEmpty()                  let phn = airContext.Phones                     .Where(x => x.AccountId.Equals(acc.Id))                     .FirstOrDefault()                  \/\/ Seat                 let bp = airContext.BoardingPasses                         .Where(x => x.PassengerId.Equals(ps.Id))                         .FirstOrDefault()                  select new PassengerRawModel                 {                     Id =  ps.Id,                     FirstName = ps.FirstName,                     LastName = ps.LastName,                     UpdateTs = ps.UpdateTs,                      FlightNum = fl.FlightNo,                     PhoneNumber = phn != null                         ? phn.PhoneValue                         : null,                      BoardingPassSeat = bp != null                         ? bp.Seat                         : null,                 };      query = query.Where(filter);      var resultQuery = query.Select(selector);      return await resultQuery.ToListAsync(); }<\/code><\/pre>\n<p>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0434\u043e\u043c\u0435\u043d\u0430 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public Task&lt;IReadOnlyCollection&lt;PassengerFlightNumModel>> GetPessengersFlightNoRawAsync(GetPassengerRequest request)     {     \/\/ \u0417\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 EF \u043f\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.      \/\/ SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", f.flight_no AS \"FlightNum\"     \/\/ FROM postgres_air.passenger AS p     \/\/ LEFT JOIN postgres_air.booking AS b ON p.booking_id = b.booking_id     \/\/ LEFT JOIN postgres_air.flight AS f ON(     \/\/     SELECT b0.flight_id     \/\/     FROM postgres_air.booking_leg AS b0     \/\/     WHERE b0.booking_id = b.booking_id     \/\/     LIMIT 1) = f.flight_id     \/\/ LEFT JOIN postgres_air.account AS a ON p.account_id = a.account_id     \/\/ WHERE p.passenger_id = ANY(@__passengerIds_0)     \/\/ AND NOT(p.passenger_id = ANY(@__passengerIds_1)     \/\/ AND p.passenger_id = ANY(@__passengerIds_1) IS NOT NULL) AND(p.update_ts &lt; @__dateTo_2 OR p.update_ts IS NULL)      \/\/\"QUERY PLAN\"     \/\/\"Hash Left Join  (cost=26608.37..36174.63 rows=5 width=20)\"     \/\/\"  Hash Cond: ((SubPlan 1) = f.flight_id)\"     \/\/\"  ->  Nested Loop Left Join  (cost=0.87..64.54 rows=5 width=24)\"     \/\/\"        ->  Index Scan using passenger_pkey on passenger p  (cost=0.43..42.29 rows=5 width=24)\"     \/\/\"              Index Cond: (passenger_id = ANY ('{1,2,3,4,5}'::integer[]))\"     \/\/\"              Filter: ((passenger_id &lt;> ALL ('{2,3}'::integer[])) OR ((passenger_id = ANY ('{2,3}'::integer[])) IS NULL))\"     \/\/\"        ->  Index Only Scan using booking_pkey on booking b  (cost=0.43..4.45 rows=1 width=8)\"     \/\/\"              Index Cond: (booking_id = p.booking_id)\"     \/\/\"  ->  Hash  (cost=15398.78..15398.78 rows=683178 width=8)\"     \/\/\"        ->  Seq Scan on flight f  (cost=0.00..15398.78 rows=683178 width=8)\"     \/\/\"  SubPlan 1\"     \/\/\"    ->  Limit  (cost=0.00..27326.28 rows=1 width=4)\"     \/\/\"          ->  Seq Scan on booking_leg b0  (cost=0.00..355241.70 rows=13 width=4)\"     \/\/\"                Filter: (booking_id = b.booking_id)\"      \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.     var filter = ConstructSpecification&lt;PassengerRawModel>(request);      \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435. EF \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u0435\u0439 \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.     \/\/ \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u0435\u0439 \u0438 \u0441\u043f\u0435\u0446\u0438\u0439\u0438\u043a\u0430\u0446\u0438\u0438 EF \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0434\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u043c\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441.     return _passengerSpecificationProvider.GetPassengersWithSpecificationsRawAsync(         filter.ToExpression(),         p => new PassengerFlightNumModel         {             Id = p.Id,             FirstName = p.FirstName,             LastName = p.LastName,             FlightNum = p.FlightNum,         }); } <\/code><\/pre>\n<p>\u0438\u043b\u0438 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public Task&lt;IReadOnlyCollection&lt;PassengerSeatModel>> GetPessengersSeatRawAsync(GetPassengerRequest request) {     \/\/ \u0417\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 EF \u043f\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.         \/\/ SELECT p.passenger_id AS \"Id\", p.first_name AS \"FirstName\", p.last_name AS \"LastName\", (     \/\/     SELECT b1.seat     \/\/     FROM postgres_air.boarding_pass AS b1     \/\/     WHERE b1.passenger_id = p.passenger_id     \/\/     LIMIT 1) AS \"BoardingPassSeat\"     \/\/ FROM postgres_air.passenger AS p     \/\/ LEFT JOIN postgres_air.booking AS b ON p.booking_id = b.booking_id     \/\/ LEFT JOIN postgres_air.flight AS f ON(     \/\/     SELECT b0.flight_id     \/\/     FROM postgres_air.booking_leg AS b0     \/\/     WHERE b0.booking_id = b.booking_id     \/\/     LIMIT 1) = f.flight_id     \/\/ LEFT JOIN postgres_air.account AS a ON p.account_id = a.account_id     \/\/ WHERE p.passenger_id = ANY(@__passengerIds_0)     \/\/ AND NOT(p.passenger_id = ANY(@__passengerIds_1)     \/\/ AND p.passenger_id = ANY(@__passengerIds_1) IS NOT NULL) AND(p.update_ts &lt; @__dateTo_2 OR p.update_ts IS NULL)      \/\/\"QUERY PLAN\"     \/\/\"Index Scan using passenger_pkey on passenger p  (cost=0.43..961587.41 rows=5 width=48)\"     \/\/\"  Index Cond: (passenger_id = ANY ('{1,2,3,4,5}'::integer[]))\"     \/\/\"  Filter: ((passenger_id &lt;> ALL ('{2,3}'::integer[])) OR ((passenger_id = ANY ('{2,3}'::integer[])) IS NULL))\"     \/\/\"  SubPlan 1\"     \/\/\"    ->  Limit  (cost=0.00..192309.02 rows=1 width=3)\"     \/\/\"          ->  Seq Scan on boarding_pass b1  (cost=0.00..576927.07 rows=3 width=3)\"     \/\/\"                Filter: (passenger_id = p.passenger_id)\"     \/\/\"JIT:\"     \/\/\"  Functions: 18\"     \/\/\"  Options: Inlining true, Optimization true, Expressions true, Deforming true\"      var filter = ConstructSpecification&lt;PassengerRawModel>(request);      return _passengerSpecificationProvider.GetPassengersWithSpecificationsRawAsync(         filter.ToExpression(),         p => new PassengerSeatModel         {             Id = p.Id,             FirstName = p.FirstName,             LastName = p.LastName,             BoardingPassSeat = p.BoardingPassSeat,          }); }<\/code><\/pre>\n<p>\u041e\u0431\u0430 \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u0430, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435, \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u043d\u0443, \u0438\u043b\u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u043c\u0443 \u043a\u0430\u043a \u0443\u0433\u043e\u0434\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u043e \u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043c\u0435\u043d\u044f \u043e\u043d \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f PassengerSpecificationProvider.<\/p>\n<p>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e \u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u043d\u0430\u043c \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0432 \u0442\u0443 \u0436\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c SQL \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0447\u0442\u043e \u0431\u044b\u043b\u0430 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<h3>\u0420\u043e\u0441\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 &#171;\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f&#187; \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u041f\u043e\u0434\u0445\u043e\u0434 \u0441 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u043c \u0447\u0438\u0441\u043b\u043e\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u043e \u043f\u0440\u0435\u0442\u0438\u0442 \u0447\u0443\u0432\u0441\u0442\u0432\u0443 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e\u0433\u043e. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0436\u0438\u0437\u043d\u0438 \u043c\u044b, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u0435\u0437\u00a0\u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u0445\u043e\u0442\u044f\u00a0\u0431\u044b \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u00a0\u043e\u043d\u0438 \u043b\u0435\u0433\u0447\u0435 \u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f. \u0423\u00a0\u043d\u0430\u0441 \u0432\u0441\u0451 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 Expression&lt;RawModel,bool> \u0432\u00a0\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432\u00a0\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 ToExpression \u0438\u0437\u00a0\u043d\u0430\u0448\u0438\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0432\u0441\u044f\u0447\u0435\u0441\u043a\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f \u0438\u0445 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439. <\/p>\n<p>\u0414\u043b\u044f\u00a0\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u00ab\u043d\u0435\u00bb, \u00ab\u0438\u00bb, \u00ab\u0438\u043b\u0438\u00bb \u043d\u0430\u0434 \u043d\u0438\u043c\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043a\u0430\u043a\u00a0\u043c\u0438\u043d\u0438\u043c\u0443\u043c<\/p>\n<p>\u00a0<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6b2\/374\/977\/6b23749773a959bdc9c806e373d95393.png\" width=\"294\" height=\"86\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6b2\/374\/977\/6b23749773a959bdc9c806e373d95393.png\"\/><\/figure>\n<p>\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0439 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0433\u0434\u0435 n &#8212; \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u0435\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438,\u00a0 k &#8212; \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0439. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430, \u0433\u0434\u0435 request \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u0432\u0441\u0435 \u044d\u0442\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b. \u0412\u044b\u0438\u0433\u0440\u044b\u0448 \u043e\u0447\u0435\u0432\u0438\u0434\u0435\u043d &#8212; \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430.<\/p>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0448\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Expressions \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. \u0412\u044b\u0437\u043e\u0432\u044b \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">_repository.GetPassengersAsync(x => x.Id > 100 &amp;&amp; x.FirstName.Equals(\u201c\u0418\u0432\u0430\u043d\u201d))<\/code><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0432\u043f\u043e\u043b\u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0430\u0432\u043e \u043d\u0430 \u0436\u0438\u0437\u043d\u044c, \u043d\u043e, \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440, \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0432\u0441\u0435 \u043f\u043e\u043b\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f\u0445, \u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e Expression \u0431\u0435\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0442\u0440\u0443\u0434\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u0432\u0438\u0434\u0443 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b,<\/p>\n<pre><code class=\"cs\">_repository.GetPassengersAsync(x =>  x.Id > 100 &amp;&amp; x.FirstName.Contains(\u201c\u0418\u0432\u0430\u043d\u201d) &amp;&amp; !(x.SecondName.Contains(\u201c\u0418\u0432\u0430\u043d\u043e\u0432\u0438\u0447\u201d) || x.SecondName.Contains(\u201c\u0412\u0430\u043b\u0435\u0440\u044c\u0435\u0432\u0438\u0447\u201d) || x.SecondName.Contains(\u201c\u0421\u0435\u043c\u0451\u043d\u043e\u0432\u0438\u0447\u201d) || x.SecondName.Contains(\u201c\u0418\u0433\u043e\u0440\u0435\u0432\u0438\u0447\u201d))  <\/code><\/pre>\n<p>\u0413\u043e\u0440\u0430\u0437\u0434\u043e \u043b\u0443\u0447\u0448\u0435 \u0431\u0443\u0434\u0443\u0442 \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0435 \u0438\u0437 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439.<\/p>\n<pre><code class=\"cs\">_repository.GetPassengersAsync(x =>  new IdAbove(100) &amp; new FirstName(\u201c\u0418\u0432\u0430\u043d\u201d)  &amp; new UnWandedSecondName(\u201c\u0418\u0432\u0430\u043d\u043e\u0432\u0438\u0447\u201d,\u201d\u0412\u0430\u043b\u0435\u0440\u044c\u0435\u0432\u0438\u0447\u201d,\u201d\u0421\u0435\u043c\u0451\u043d\u043e\u0432\u0438\u0447\u201d,\u201d\u0418\u0433\u043e\u0440\u0435\u0432\u0438\u0447\u201d)) <\/code><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434: \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u201c\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u201d \u0432\u044b\u0433\u043e\u0434\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043c, \u0433\u0434\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u0438\u043b\u0438 \u0441\u043e\u0442\u0435\u043d \u043f\u043e\u043b\u0435\u0439 \u0438 \u043a \u043d\u0438\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445.\u00a0<\/p>\n<h3>\u0412 \u0447\u0451\u043c \u0441\u0438\u043b\u0430, \u0431\u0440\u0430\u0442?<\/h3>\n<p>\u041a\u0430\u043a \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0443\u0436\u0435 \u0432\u044b\u0448\u0435, \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043f\u043b\u044e\u0441 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0442\u0430\u043c, \u0433\u0434\u0435 \u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c &#8212; \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0434\u043e\u043c\u0435\u043d\u0430.\u00a0<\/p>\n<p>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u044d\u0442\u043e \u0437\u043d\u0430\u043d\u0438\u044f \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0437\u043d\u0430\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043e \u0441\u0430\u043c\u043e\u0439 \u0441\u0435\u0431\u0435, \u0442.\u0435. \u043c\u044b \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0433\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u044f, \u0441\u043b\u043e\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438. \u0418 \u0435\u0441\u043b\u0438 \u043c\u044b \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u044e \u0432\u0438\u0434\u043e\u0432 \u043d\u0430 \u043d\u0430\u0448\u0435\u0439 \u043f\u043b\u0430\u043d\u0435\u0442\u0435, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u0431\u0435\u0434\u0438\u043b\u0438 \u0442\u0435 \u0432\u0438\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438. \u041a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u0440\u044b\u043d\u043a\u0435 IT &#8212; \u044d\u0442\u043e \u0442\u0430 \u0436\u0435 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u044f, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442 \u0432\u044b\u0436\u0438\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e, \u0442.\u043a. \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u0438\u043c. \ud83d\ude42 \u0423\u0434\u0430\u0447\u0438.<\/p>\n<h3>P.S. \u041e \u043f\u0440\u0438\u043c\u0435\u0440\u0435<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0411\u0414 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043a \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043a\u043d\u0438\u0433\u0435 \u00ab\u0414\u043e\u043c\u0431\u0440\u043e\u0432\u0441\u043a\u0430\u044f, \u0411\u0435\u0439\u043b\u0438\u043a\u043e\u0432\u0430, \u041d\u043e\u0432\u0438\u043a\u043e\u0432: <a href=\"https:\/\/www.labirint.ru\/books\/828097\/\">\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 PostgreSQL<\/a>\u00bb, \u0430\u0432\u0442\u043e\u0440\u044b \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0411\u0414 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u0445 \u0434\u043e 11\u041c \u0437\u0430\u043f\u0438\u0441\u0435\u0439.<\/p>\n<p>\u0411\u044d\u043a\u0430\u043f \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/drive.google.com\/drive\/folders\/13F7M80Kf_somnjb-mTYAnh1hW1Y_g4kJ\">\u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c<\/a>, \u0444\u0430\u0439\u043b postgres_air_2023.backup<\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0432 \u0431\u044d\u043a\u0430\u043f \u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0435\u0433\u043e \u0432 \u043f\u0430\u043f\u043a\u0443 %\\SpecificationPatternPoC\\pgAdmin\\pgAdmin_storage\\admin_admin.com, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0431\u044d\u043a\u0430\u043f \u0432 pgAmdin (localhost:5050)<\/p>\n<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0434\u0440\u0443\u0433\u0438\u0445 \u0430\u0432\u0442\u043e\u0440\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043c\u043d\u043e\u044e \u0434\u043b\u044f \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0443 \u0441\u0442\u0430\u0442\u044c\u0438. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0438\u043c \u0432\u0441\u0435\u043c. ?<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/jugru\/articles\/423891\/\">https:\/\/habr.com\/ru\/companies\/jugru\/articles\/423891\/<\/a><\/p>\n<p><a href=\"https:\/\/enterprisecraftsmanship.com\/posts\/specification-pattern-c-implementation\/\">https:\/\/enterprisecraftsmanship.com\/posts\/specification-pattern-c-implementation\/<\/a><\/p>\n<p><a href=\"https:\/\/fabio.marreco.dev\/blog\/2018\/specificationpattern-with-entityframework\/\">https:\/\/fabio.marreco.dev\/blog\/2018\/specificationpattern-with-entityframework\/<\/a><\/p>\n<h2>UPD<\/h2>\n<p>\u041a\u0430\u043a \u0432\u0435\u0440\u043d\u043e \u043f\u043e\u0434\u043c\u0435\u0447\u0435\u043d\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0438\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0442\u043e\u0440\u043e\u0432, \u0443 \u043d\u0430\u0441 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f &#171;\u043b\u0435\u0441 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439&#187;. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e, \u043c\u043e\u0436\u043d\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c KeySelector \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043a \u043a\u0430\u043a\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u0435\u0451 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \/\/\/ &lt;\/summary> \/\/\/ &lt;param name=\"keySelector\">\u041f\u043e\u043b\u0435 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0444\u0438\u043b\u044c\u0440\u043e\u0432\u0430\u0442\u044c, \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u0438\u0434\u0435 x=>x.Id .&lt;\/param> \/\/\/ &lt;param name=\"passnegerIds\">\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432.&lt;\/param> public class IdsSpecification&lt;T>(Expression&lt;Func&lt;T, int>> keySelector, int[] passnegerIds) : Specification&lt;T>     where T : class {     private readonly List&lt;int> Ids = [.. passnegerIds];     private readonly Expression&lt;Func&lt;T, int>> keySelector = keySelector;      private static MethodInfo ContainsMethodInfo => typeof(List&lt;int>).GetMethod(nameof(List&lt;int>.Contains));       public override Expression&lt;Func&lt;T, bool>> ToExpression()     {         var fieldName = ((MemberExpression) keySelector.Body).Member.Name;         var param = Expression.Parameter(typeof(T), fieldName);         var call = Expression.Call(Expression.Constant(Ids), ContainsMethodInfo, Expression.Property(param, fieldName));          return Expression.Lambda&lt;Func&lt;T, bool>>(call, param);     } }<\/code><\/pre>\n<p>\u0412 \u0441\u0442\u0440\u043e\u043a\u0435 12 \u043c\u044b \u0432\u044b\u0437\u0432\u0430\u043b\u0438 \u0434\u0440\u0435\u0432\u043d\u0435\u0435 \u0437\u043b\u043e, \u043d\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043d\u0435\u043c\u0443 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u0430\u043b\u043e, \u0435\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0411\u0414. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cs\">var filter = (Specification&lt;T>) new IdsSpecification&lt;T>(x => x.Id, request.PassengerIds);<\/code><\/pre>\n<p>\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0434\u0430\u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0434\u0430\u0442\u044b \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b. \/\/\/ &lt;param name=\"keySelector\">\u041f\u043e\u043b\u0435 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c.&lt;\/param> \/\/\/ &lt;param name=\"dateStart\">\u0414\u0430\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438.&lt;\/param> \/\/\/ &lt;param name=\"dateEnd\">\u0414\u0430\u0442\u0430 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438.&lt;\/param> \/\/\/ &lt;param name=\"defaultValue\">\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.&lt;\/param> \/\/\/ &lt;\/summary public class DateIntervalSpecification&lt;T>(     Expression&lt;Func&lt;T, DateTime?>> keySelector,      DateTime? dateStart, DateTime? dateEnd, bool defaultValue = false) : Specification&lt;T>     where T : class {     private readonly Expression&lt;Func&lt;T, DateTime?>> keySelector = keySelector;     private readonly DateTime? dateStart = dateStart;     private readonly DateTime? dateEnd = dateEnd;       public override Expression&lt;Func&lt;T, bool>> ToExpression()     {         var fieldName = ((MemberExpression)keySelector.Body).Member.Name;         var param = Expression.Parameter(typeof(T), fieldName);                 var expressionNull = Expression.Constant(null);          if (dateStart.HasValue &amp;&amp; !dateEnd.HasValue)         {             var dateFrom = GetStartDate(dateStart.Value);             var expressionFrom = Expression.Constant(dateFrom);              var orElse = Expression.OrElse(                             GreaterThanNulable(Expression.Property(param, fieldName), expressionFrom),                             Expression.Equal(Expression.Property(param, fieldName), expressionNull));              return Expression.Lambda&lt;Func&lt;T, bool>>(orElse,param);         }          if (dateEnd.HasValue &amp;&amp; !dateStart.HasValue)         {             var dateTo = GetEndDate(dateEnd.Value);                          var expressionTo = Expression.Constant(dateTo);              var orElse = Expression.OrElse(                     GreaterThanNulable(expressionTo, Expression.Property(param, fieldName)),                     Expression.Equal(Expression.Property(param, fieldName), expressionNull));              return Expression.Lambda&lt;Func&lt;T, bool>>(orElse, param);         }          if (dateEnd.HasValue &amp;&amp; dateStart.HasValue)         {             var dateFrom = GetStartDate(dateStart.Value);             var expressionFrom = Expression.Constant(dateFrom);              var dateTo = GetEndDate(dateEnd.Value);             var expressionTo = Expression.Constant(dateTo);              var twoDateFilterExpression = Expression.AndAlso(                     GreaterThanNulable(Expression.Property(param, fieldName), expressionFrom),                     GreaterThanNulable(expressionTo,Expression.Property(param, fieldName)));              var orElse = Expression.OrElse(                     twoDateFilterExpression,                     Expression.Equal(Expression.Property(param, fieldName), expressionNull));              return Expression.Lambda&lt;Func&lt;T, bool>>(orElse, param);         }          return x => defaultValue;     }      private static DateTime GetStartDate(DateTime requestTo) =>         DateTime.SpecifyKind(requestTo.Date, DateTimeKind.Utc);      private static DateTime GetEndDate(DateTime requestFrom) =>         DateTime.SpecifyKind(requestFrom.Date.AddDays(1), DateTimeKind.Utc);      private static BinaryExpression GreaterThanNulable(Expression left, Expression right)     {         if (IsNullableType(left.Type) &amp;&amp; !IsNullableType(right.Type))         {             right = Expression.Convert(right, left.Type);              return Expression.GreaterThan(left, right);         }                  if (!IsNullableType(left.Type) &amp;&amp; IsNullableType(right.Type))         {             left = Expression.Convert(left, right.Type);         }          return Expression.GreaterThan(left, right);     }      private static bool IsNullableType(Type type) =>          type.IsGenericType &amp;&amp; type.GetGenericTypeDefinition() == typeof(Nullable&lt;>); }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0442\u0443\u0442 \u043e\u0431\u043e\u0448\u043b\u043e\u0441\u044c \u0431\u0435\u0437 using System.Reflection. <\/p>\n<p>\u041e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">filter &amp;= new DateIntervalSpecification&lt;T>(x => x.UpdateTs, request.UpdateTsStart, request.UpdateTsEnd);<\/code><\/pre>\n<p>\u0412 \u0442\u0430\u043a\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043b\u044e\u0431\u044b\u043c \u043f\u043e\u043b\u0435\u043c \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0430 \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e keySelector-\u043e\u0432, \u0442\u043e \u0441 \u043b\u044e\u0431\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438. <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 Nuget, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0438\u043b\u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043e\u0442\u0431\u043e\u0440\u0430, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u044e, \u0442\u0430\u043c \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u043e, \u0438\u0437\u0431\u0435\u0433\u0430\u044f \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u044b, \u0430 \u0433\u0434\u0435 \u041d\u0415 \u043d\u0443\u0436\u043d\u043e &#8212; \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. <\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0432\u0441\u0435\u043c, \u043a\u0442\u043e \u043f\u0440\u043e\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043b, \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u0430\u0451\u0442 \u043f\u043e\u0447\u0432\u0443 \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0439, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u043e.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/800813\/\"> https:\/\/habr.com\/ru\/articles\/800813\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041e \u0447\u0451\u043c \u0441\u0442\u0430\u0442\u044c\u044f?\u00a0<\/h3>\n<p>\u041e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0435 \u00ab\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c, \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043c \u043a\u043e\u0434\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 &#8212; \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u0447\u043d\u043e. \u041f\u043e\u0447\u0435\u043c\u0443? &#8212; \u0447\u0438\u0442\u0430\u0435\u043c \u043d\u0438\u0436\u0435.\u00a0<\/p>\n<h3>\u042d\u0442\u043e\u0433\u043e \u043c\u0430\u043b\u043e, \u0447\u0442\u043e \u0435\u0449\u0451?\u00a0<\/h3>\n<p>\u041a \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 Web API \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0430\u043d\u0435\u043c\u0438\u0447\u043d\u043e\u0439 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 MediatR, Postgres \u0438 Docker Compose. \u0412\u0441\u0451, \u043a\u0430\u043a \u0412\u044b \u043b\u044e\u0431\u0438\u0442\u0435 \u0438, \u0442\u0430\u043a\u0438 \u0434\u0430, \u0430\u043d\u0435\u043c\u0438\u0447\u043d\u043e\u0439 \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u043c\u044b \u043d\u0430\u0440\u0443\u0448\u0438\u043c \u0438\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044e, \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u043d\u0438\u043a\u0443\u0434\u0430.\u00a0<\/p>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043b\u0430\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f SQL &#8212; \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 EF\u00a0 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0438 \u0431\u0435\u0437 \u043d\u0438\u0445 (\u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c).<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430: <a href=\"https:\/\/github.com\/potandr1977\/SpecificationPatternPoC\"><u>\u0442\u0443\u0442<\/u><\/a><\/p>\n<h3>\u041f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430<\/h3>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u0435\u0440\u0435\u0432\u043e\u0437\u043a\u0443 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u0430\u0432\u0438\u0430\u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043e\u043c. \u0411\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u043d\u0430 \u0435\u0451 \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<h3>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439<\/h3>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0438\u0437 \u043d\u0430\u0441 \u0432\u0438\u0434\u0435\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u044d\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0440\u0435\u0439\u0441\u0430\u0445 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432:<\/p>\n<pre><code class=\"cs\">\/\/ \u041c\u0435\u0442\u043e\u0434 \u043d\u0430 Over9000 \u0441\u0442\u0440\u043e\u043a. public async Task&lt;List&lt;\u043a\u0430\u043a\u0430\u044f\u0442\u043e\u041c\u043e\u0434\u0435\u043b\u044c>> GetPessengersFlightNoAsync(\u043a\u0430\u043a\u043e\u0439\u0442\u043e\u0417\u0430\u043f\u0440\u043e\u0441) {     var query = from smth1  in \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442.Something1                   join smth2 in \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442.Something2                   \u2026..                   join smth20 in \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442.Something20                   where \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f                   select new \/\/ \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0442\u0438\u043f                   {                        Field1,                       \u2026                       Field30                   };      if (request.Field1 != null)     {         query = query.Where( x => \u0443\u0441\u043b\u043e\u0432\u0438\u0435_\u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0435\u0435_\u043e\u0442_\u043f\u043e\u043b\u0435\u0439_\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u04301);     }     \u2026     if (request.Field15 != null)     {         query = query.Where( x => \u0443\u0441\u043b\u043e\u0432\u0438\u0435_\u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0435\u0435_\u043e\u0442_\u043f\u043e\u043b\u0435\u0439_\u0440\u0435\u043a\u0432\u0435\u0441\u0442\u043015);     }     var anonimousModels = await query.ToListAsync();      return anonimousModels.To\u041a\u0430\u043a\u0438\u0435\u0442\u043e\u0422\u043e\u041c\u043e\u0434\u0435\u043b\u0438(): }<\/code><\/pre>\n<p>\u0412 \u0447\u0451\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430? \u041e\u043d \u043e\u0433\u0440\u043e\u043c\u0435\u043d \u0438 \u0435\u0433\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u043e\u0442\u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0442\u044c \u0432 \u043d\u0430\u0431\u043e\u0440 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 select \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0442\u0438\u043f.\u00a0<\/p>\n<p>C# \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0441 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c \u043e\u0442 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0438\u0445 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043d\u0430\u0448\u0443 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c.\u00a0<\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b &#8212; \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0443\u0441\u043f\u0435\u0445, \u043d\u043e \u0442\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432\u044b\u0440\u0430\u0441\u0442\u0435\u0442 \u043a\u0430\u043a \u043f\u043e\u043f\u043a\u043e\u0440\u043d \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0433\u0440\u0435\u0432\u0430, \u0430 \u043e\u043d\u043e \u043d\u0430\u043c \u043d\u0430\u0434\u043e? &#8212; \u043d\u0435\u0442!<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436\u0438 \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 select, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u0434\u0430\u043d\u043d\u044b\u043c \u0432 \u0432\u0438\u0434\u0435 \u043a\u0430\u043a\u043e\u0439\u0442\u043e\u041a\u043e\u0440\u0442\u0435\u0436.Item1, \u0447\u0442\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0442 \u0447\u0443\u0432\u0441\u0442\u0432\u0443 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e\u0433\u043e \u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u043a \u043d\u044d\u0439\u043c\u0438\u043d\u0433\u0443.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u0437\u0430\u0442\u0440\u0443\u0434\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<h3>\u041f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435<\/h3>\n<p>\u0415\u0441\u0442\u044c \u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0435\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a, \u0447\u0435\u043c \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u043e\u0433\u043e \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0430. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 Domain Driven Design \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0449\u0438\u0442\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u0437\u0430\u0449\u0438\u0442\u0430 \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438 \u043e\u0442 \u043f\u0435\u0440\u0435\u0442\u0435\u043a\u0430\u043d\u0438\u044f \u043d\u0430 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u044e. \u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043e\u0442\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0431\u0438\u0437\u043d\u0435\u0441 \u043b\u043e\u0433\u0438\u043a\u0438 \u0438 \u043e\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0443 \u043d\u0430\u0441 \u2026 \u043d\u0430 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438, \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044d\u0442\u043e \u043a\u043e\u0440\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0431\u0435\u0434.<\/p>\n<p>\u041a\u0430\u043a \u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445? \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435:<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0418, \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u043e\u0441\u0430\u0434\u043a\u0438 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u0432 \u0441\u0430\u043c\u043e\u043b\u0451\u0442\u0435, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u0442\u043e\u0440\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443, \u0430 \u0435\u0441\u043b\u0438 N-\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 N \u0446\u0435\u043f\u043e\u0447\u0435\u043a.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u0438\u0442\u044c 90% \u043a\u043e\u0434\u0430 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439, \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044f \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c join-\u043e\u0432 \u0438 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c if-\u043e\u0432, \u0442.\u043a. \u043a\u043e\u0434 \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0430\u0451\u0442\u0441\u044f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0443.<\/p>\n<h3>\u041f\u0430\u0442\u0442\u0435\u0440\u043d &#171;\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f&#187;. \u0411\u043b\u0435\u0441\u043a<\/h3>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0441 N \u0434\u043e 1 \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0445 \u0440\u0435\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u00a0 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u201c\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u201d, \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0432 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0430 \u043e\u0434\u0438\u043d DbSet \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0432 DbContext, \u0442.\u0435. \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u043d\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 100 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u201cGetPassenger\u0427\u0442\u043e\u0422\u043e\u0422\u0430\u043c\u201d \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 PassengerController, \u0442\u043e \u0432\u0441\u0435 \u043e\u043d\u0438 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b 1 \u043c\u0435\u0442\u043e\u0434\u043e\u043c GetPassengers,<\/p>\n<p>\u043d\u0443 \u0438\u043b\u0438 GetPassengersWithSpecifications, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043e\u0442\u0431\u043e\u0440\u0430 \u00ab\u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0435\u0442\u00bb \u043d\u0430\u00a0\u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0434\u043e\u043c\u0435\u043d\u0430, \u0447\u0442\u043e\u00a0\u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0432\u00a0\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438, \u0430\u00a0\u0442\u0430\u043a\u0436\u0435 \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0411\u0414 \u043d\u0430\u00a0\u0434\u0440\u0443\u0433\u0443\u044e. Postgres \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430\u00a0MongoDb \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u00a0\u0434\u043e\u043c\u0435\u043d\u0435 \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0435\u00a0\u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f, \u0442.\u043a. \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442 Expression, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043a\u0430\u043a \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 EF \u0442\u0430\u043a \u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 MongoDbDriver.<\/p>\n<figure class=\"\"><\/figure>\n<p>\u0418\u0442\u0430\u043a, \u0432 DbContext\u00a0 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0432 \u043d\u0430\u0448 \u0434\u043e\u043c\u0435\u043d.<\/p>\n<p>\u0423 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 4 \u0444\u0430\u0439\u043b\u0430:\u00a0<\/p>\n<p>Specification.cs &#8212; \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u0433\u0434\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u0438, \u0434\u0438\u0437\u044a\u044e\u043d\u043a\u0446\u0438\u0438 \u0438 \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0436\u0435\u043b\u0430\u043d\u0438\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439. \/\/\/ &lt;\/summary> public abstract class Specification&lt;T> {     \/\/ \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448\u0443 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 Expression.     public abstract Expression&lt;Func&lt;T, bool>> ToExpression();      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u0448\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043d\u0430 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0441\u0442\u044c.     public virtual bool IsSatisfiedBy(T entity)     {         Func&lt;T, bool> predicate = ToExpression().Compile();         return predicate(entity);     }      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u0438, \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\" \u043d\u0430\u0434 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438.     \/\/\/ \u041d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.     \/\/\/ \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public Specification&lt;T> And(Specification&lt;T> specification) =>         new AndSpecification&lt;T>(this, specification);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0438\u0437\u044a\u044e\u043d\u043a\u0446\u0438\u0438, \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\u041b\u0418\" \u043d\u0430\u0434 \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\u043c\u0438.      \/\/\/ \u041d\u0430\u0434 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0438 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.     \/\/\/ \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public Specification&lt;T> Or(Specification&lt;T> specification) =>         new OrSpecification&lt;T>(this, specification);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u044f.     \/\/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;returns>&lt;\/returns>     public Specification&lt;T> Not() => new NotSpecification&lt;T>(this);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c false \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static bool operator false (Specification&lt;T> specification) => false;      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c true \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"specification\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static bool operator true(Specification&lt;T> specification) => true;      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\".     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"left\">&lt;\/param>     \/\/\/ &lt;param name=\"right\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static Specification&lt;T> operator &amp;(Specification&lt;T> left, Specification&lt;T> right) =>         left.And(right);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \"\u0418\u041b\u0418\".     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"left\">&lt;\/param>     \/\/\/ &lt;param name=\"right\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static Specification&lt;T> operator |(Specification&lt;T> left, Specification&lt;T> right) =>         left.Or(right);      \/\/\/ &lt;summary>     \/\/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u044f.     \/\/\/ &lt;\/summary>     \/\/\/ &lt;param name=\"left\">&lt;\/param>     \/\/\/ &lt;param name=\"right\">&lt;\/param>     \/\/\/ &lt;returns>&lt;\/returns>     public static Specification&lt;T> operator !(Specification&lt;T> specification) => specification.Not(); } <\/code><\/pre>\n<p>AndSpecification.cs &#8212; \u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u0438 \u0434\u0432\u0443\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u0442.\u0435. \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c VasyaAndPetia =\u00a0 Vasya &amp; Petia.<\/p>\n<p>OrSpecification.cs &#8212; \u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0434\u0438\u0437\u044a\u044e\u043d\u043a\u0446\u0438\u0438 \u0434\u0432\u0443\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439, \u0442.\u0435. \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c VasyaAndPetia =\u00a0 Vasya | Petia.<\/p>\n<p>NotSpecification.cs &#8212; \u041a\u043b\u0430\u0441\u0441 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0438\u0441\u0430\u0442\u044c NotVasya = !Vasya.<\/p>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c AndSpecification, OrSpecification \u0438 NotSpecification \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b AndAlso, OrElse \u0438 Not \u043a\u043b\u0430\u0441\u0441\u0430 Expression \u0438 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0434\u0435\u0442\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0442\u044f\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0439\u0441\u043e\u043c \u0432 \u0430\u044d\u0440\u043e\u043f\u043e\u0440\u0442 \u041b\u043e\u0441-\u0410\u043d\u0434\u0436\u0435\u043b\u0435\u0441\u0430 \u043f\u043e \u0431\u0438\u043b\u0435\u0442\u0430\u043c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 $300, \u0442\u043e \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:\u00a0<\/p>\n<pre><code>var laKidsHigher300 = AgeUnder18Spec &amp; ArrivalAirportLASpec &amp; !PriceUnder300Spec;<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043e\u0442\u0431\u043e\u0440\u0430, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u0432 \u043e\u0431\u044a\u0435\u043c \u043a\u043e\u0434\u0430. \u041c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430 &#8212; \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u0435\u0440\u043d\u0435\u0435, \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c. \u0413\u0434\u0435 \u043e\u043d\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043a\u0440\u0438\u043d:<\/p>\n<figure class=\"\"><\/figure>\n<p>\u041d\u0430 \u0431\u0430\u0437\u0435 Specification.cs \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432 \u043f\u043e \u0438\u0445 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c.\u00a0<\/p>\n<p>PassengerIdsSpecification.cs<\/p>\n<pre><code>\/\/\/ &lt;summary> \/\/\/ \u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u0430 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432. \/\/\/ &lt;\/summary> \/\/\/ &lt;param name=\"passnegerIds\">\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u043e\u0432.&lt;\/param> public class PassengerIdsSpecification&lt;T>(int[] passnegerIds) : Specification&lt;T>     where T : IFiltrationFieldsSet {     private readonly int[] passengerIds = passnegerIds;      public override Expression&lt;Func&lt;T, bool>> ToExpression() =>         p => passengerIds.Contains(p.Id); }<\/code><\/pre>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044d\u0442\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<pre><code class=\"cs\">\/\/\/ &lt;summary> \/\/\/ \u0421\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u0431\u043e\u0440\u0430 \u043f\u043e \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u0434\u0430\u0442\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u043f\u0430\u0441\u0441\u0430\u0436\u0438\u0440\u0435 (UpdateTs) \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b. \/\/\/ &lt;\/summary public<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-371027","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=371027"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371027\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=371027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=371027"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=371027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}