{"id":287476,"date":"2018-08-16T14:10:01","date_gmt":"2018-08-16T10:10:01","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=287476"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=287476","title":{"rendered":"Internal DSL &#038; Expression Trees \u2014 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 serialize, copy, clone, equals (\u0427\u0430\u0441\u0442\u044c I)"},"content":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/419759\/\" class=\"post__text post__text-html js-mediator-article\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/_c\/m3\/gr\/_cm3grewmg9yewpcch1nqkl2ho8.png\"><\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u0434\u0432\u043e\u0439\u043d\u043e\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044e API <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/expression-trees\/\">Expression Trees<\/a> \u2014 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430. \u0420\u0430\u0437\u0431\u043e\u0440 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u043e\u043d\u0438 \u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 <a href=\"https:\/\/martinfowler.com\/books\/dsl.html\">Internal DSL<\/a>), \u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u2014 \u043d\u0430\u0431\u043e\u0440\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<p>\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0443 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 <strong>\u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432: serialize, copy, clone, equals<\/strong>. \u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 serialize \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e (\u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430\u043c\u0438) \u0432 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 &#171;\u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435&#187; \u0437\u043d\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0418\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0435\u0442 &#171;\u043d\u0435\u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u044e\u0449\u0435\u0439 \u043a\u0430\u043a\u0438\u0435 \u0443\u0437\u043b\u044b \u0434\u0435\u0440\u0435\u0432\u0430 \u043d\u0430\u0434\u043e \u043e\u0431\u043e\u0439\u0442\u0438, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 &#171;\u043d\u0435 \u0440\u0443\u043a\u0430\u043c\u0438&#187; \u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c. <strong>Inernal DSL \u0438 \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u0431\u0445\u043e\u0434\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 (\u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435: \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 c \u043f\u0440\u043e\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0443\u0437\u043b\u043e\u0432) <\/strong>. \u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0441\u043a\u0440\u043e\u043c\u043d\u044b\u0439, \u043d\u043e \u043e\u043d \u0432\u0430\u0436\u0435\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u0443, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e Internal <strong>DSL Includes<\/strong> (\u0434\u0438\u0430\u043b\u0435\u043a\u0442 \u0442\u043e\u0433\u043e Include\/ThenInclude \u0447\u0442\u043e \u0438\u0437 <a href=\"https:\/\/docs.microsoft.com\/en-us\/ef\/#pivot=efcore\">EF Core<\/a>) \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044e Internal DSL \u0432 \u0446\u0435\u043b\u043e\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. <\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"vvedenie\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">var p = new Point(){X=-1,Y=1}; \/\/ which has better performance ? var json1 = JsonConvert.SerializeObject(p);  var json2 = $\"{{\\\"X\\\":{p.X}, \\\"Y\\\":{p.Y}}}\";<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u2014 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0439 (\u0443\u0437\u043b\u044b \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b \u0438 &#171;\u0437\u0430\u0431\u0438\u0442\u044b \u0432 \u043a\u043e\u0434&#187;), \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043f\u043e\u0441\u043e\u0431 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u0441\u043b\u043e\u0436\u043d\u0435\u0439. \u041d\u043e \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044e (\u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0438 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e) \u2014 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f (\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u0436\u0435 \u0442\u043e \u0447\u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e<br \/>  \u0433\u0434\u0435 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044f, \u0430 \u0433\u0434\u0435 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u043d\u0442\u0430\u0439\u043c). <\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">var p = new Point(){X=-1,Y=1}; \/\/ which has better performance ? var json1 = JsonConvert.SerializeObject(p);  var formatter = JsonManager.ComposeFormatter&lt;Point&gt;(); var json2 = formatter(p);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c <code>JsonManager.ComposeFormatter<\/code> \u2014 <a href=\"https:\/\/www.nuget.org\/packages\/DashboardCode.Routines\/\">\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442<\/a>. \u041f\u0440\u0430\u0432\u0438\u043b\u043e \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u0445\u043e\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043d\u043e \u043e\u043d\u043e \u0437\u0432\u0443\u0447\u0438\u0442 \u0442\u0430\u043a &#171;\u043f\u0440\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 value type \u043e\u0431\u043e\u0439\u0434\u0438 \u0432\u0441\u0435 \u043f\u043e\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f&#187;. \u0415\u0441\u043b\u0438 \u0436\u0435 \u0435\u0433\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e: <\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">\/\/ \u043e\u0431\u0445\u043e\u0434 \u0437\u0430\u0434\u0430\u043d \u044f\u0432\u043d\u043e var formatter2 = JsonManager.ComposeFormatter&lt;Point&gt;(    chain=&gt;chain          .Include(e=&gt;e.X)       .Include(e=&gt;e.Y)  \/\/ DSL Includes )<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c DSL Includes. \u0410\u043d\u0430\u043b\u0438\u0437\u0443 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444 (\u0443\u0441\u0442\u0443\u043f\u043e\u043a?) \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 DSL\u043e\u043c, \u043f\u0440\u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441, \u043d\u0435 \u0443\u0434\u0435\u043b\u044f\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0443 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f &#171;\u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0431\u0445\u043e\u0434\u0430&#187; (\u0442.\u0435. \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044f \u0444\u043e\u0440\u043c\u0443 \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445), \u0430\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u0443\u044e \u0447\u0442\u043e C# \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c &#171;\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440&#187; \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Expression Trees. <\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u0430\u043a \u043e\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 &#8212; \u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0438 \u0433\u0438\u0434 \u043f\u043e \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 Expression Trees&#8230;<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043e\u0442 <code>formatter<\/code> \u043a <code>serilizer<\/code> (\u043f\u043e\u043a\u0430 \u0431\u0435\u0437 expression trees):<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\"> Func&lt;StringBuilder, Point, bool&gt;  serializer = ... \/\/ later  string formatter(Point p)             {                 var stringBuilder = new StringBuilder();                 serializer(stringBuilder, p);                 return  stringBuilder.ToString();             }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c <code>serializer<\/code> \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 (\u0435\u0441\u043b\u0438 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043a\u043e\u0434\u043e\u043c):<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Expression&lt;Func&lt;StringBuilder, Point, bool&gt;&gt; serializerExpression =      SerializeAssociativeArray(sb, p,           (sb1, t1) =&gt; SerializeValueProperty(sb1, t1, \"X\", o =&gt; o.X, SerializeValueToString),           (sb4, t4) =&gt; SerializeValueProperty(sb1, t1, \"Y\", o =&gt; o.Y,  SerializeValueToString)     ); Func&lt;StringBuilder, Point, bool&gt; serializer = serializerExpression.Compile();  <\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0447\u0435\u043c \u0442\u0430\u043a &#171;\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e&#187;, \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435\u043b\u044c\u0437\u044f \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 &#171;\u0442\u043e\u0447\u043a\u0443 \u0441 \u0437\u0430\u043f\u044f\u0442\u043e\u0439&#187;? \u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043e\u0442 \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0442\u0438\u043f\u0430 <code>Expression&lt;Func&lt;StringBuilder, Box, bool&gt;&gt;<\/code>, \u0430 &#171;\u0442\u043e\u0447\u043a\u0443 \u0441 \u0437\u0430\u043f\u044f\u0442\u043e\u0439&#187; \u043d\u0435\u043b\u044c\u0437\u044f.<br \/>  \u041f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435\u043b\u044c\u0437\u044f \u0431\u044b\u043b\u043e \u043f\u0440\u044f\u043c\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>Func&lt;StringBuilder, Point, bool&gt; serializer = (sb,p)=&gt;SerializeAssociativeArray(sb,p,...<\/code>? \u041c\u043e\u0436\u043d\u043e, \u043d\u043e \u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u044e \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430, \u0430 \u0441\u0431\u043e\u0440\u043a\u0443 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043a\u043e\u0434\u043e\u043c) expression tree, \u0441 \u043f\u043e\u043b\u0441\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 \u0432 \u0434\u0435\u043b\u0435\u0433\u0430\u0442, \u0432 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>serializerExpression<\/code> \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u043e \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u2014 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 (\u043d\u0438\u0436\u0435). <\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0447\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0432 \u0441\u0430\u043c\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0438: <code>SerializeAssociativeArray<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 <code>params Func&lt;..&gt; propertySerializers<\/code> \u043f\u043e \u0447\u0438\u0441\u043b\u0443 \u0443\u0437\u043b\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0434\u043e \u043e\u0431\u043e\u0439\u0442\u0438. \u041e\u0431\u0445\u043e\u0434 \u043e\u0434\u043d\u0438\u0445 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0434\u0430\u043d \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440\u0430\u043c\u0438 &#171;\u043b\u0438\u0441\u0442\u044c\u0435\u0432&#187; <code>SerializeValueProperty<\/code>(\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435\u0440 <code>SerializeValueToString<\/code>), \u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u043e\u043f\u044f\u0442\u044c <code>SerializeAssociativeArray<\/code> (\u0442.\u0435. \u0432\u0435\u0442\u043e\u043a) \u0438 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 (\u0434\u0435\u0440\u0435\u0432\u043e) \u043e\u0431\u0445\u043e\u0434\u0430. <\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b Point \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e NextPoint:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">var @delegate =      SerializeAssociativeArray(sb, p,           (sb1, t1) =&gt; SerializeValueProperty(sb1, t1, \"X\", o =&gt; o.X, SerializeValueToString),           (sb4, t4) =&gt; SerializeValueProperty(sb1, t1, \"Y\", o =&gt; o.Y,  SerializeValueToString),           (sb4, t4) =&gt; SerializeValueProperty(sb1, t1, \"NextPoint\", o =&gt; o.NextPoint,                  (sb4, t4) =&gt;SerializeAssociativeArray(sb1, p1,                     (sb1, t1) =&gt; SerializeValueProperty(sb2, t2, \"X\", o =&gt; o.X, SerializeValueToString),                     (sb4, t4) =&gt; SerializeValueProperty(sb2, t2, \"Y\", o =&gt; o.Y,  SerializeValueToString)                 )            )     );<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0442\u0440\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>SerializeAssociativeArray<\/code>, <code>SerializeValueProperty<\/code>, <code>SerializeValueToString<\/code> \u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0435:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Serialize&#8230;<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">public static bool SerializeAssociativeArray&lt;T&gt;(StringBuilder stringBuilder, T t, params Func&lt;StringBuilder, T, bool&gt;[] propertySerializers)         {             var @value = false;             stringBuilder.Append('{');             foreach (var propertySerializer in propertySerializers)             {                 var notEmpty = propertySerializer(stringBuilder, t);                 if (notEmpty)                 {                     if (!@value)                         @value = true;                     stringBuilder.Append(',');                 }             };             stringBuilder.Length--;             if (@value)                 stringBuilder.Append('}');             return @value;         }          public static bool SerializeValueProperty&lt;T, TProp&gt;(StringBuilder stringBuilder, T t, string propertyName,             Func&lt;T, TProp&gt; getter, Func&lt;StringBuilder, TProp, bool&gt; serializer) where TProp : struct         {             stringBuilder.Append('\"').Append(propertyName).Append('\"').Append(':');             var value = getter(t);             var notEmpty = serializer(stringBuilder, value);             if (!notEmpty)                 stringBuilder.Length -= (propertyName.Length + 3);             return notEmpty;         }          public static bool SerializeValueToString&lt;T&gt;(StringBuilder stringBuilder, T t) where T : struct         {             stringBuilder.Append(t);             return true;         }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u041c\u043d\u043e\u0433\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0442\u0443\u0442 \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b (\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u0441\u0441\u044b\u043b\u043e\u0447\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438 nullable). \u0418 \u0432\u0441\u0435 \u0436\u0435 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0443 <em>json<\/em> \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435, \u0430 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u044d\u0442\u043e \u0435\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>SerializeArray<\/code>, <code>SerializeNullable<\/code>, <code>SerializeRef<\/code>.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 Expression Tree, \u043d\u0435 \u0434\u0438\u043d\u0430\u043c\u0438\u0435\u0447\u0435\u0441\u043a\u043e\u0435, \u043d\u0435 <em>eval \u0432 C#<\/em>.<\/p>\n<p>  <\/p>\n<p>\u0423\u0432\u0438\u0434\u0435\u0442\u044c \u043a\u0430\u043a Expression Tree \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0432 \u0434\u0432\u0430 \u0448\u0430\u0433\u0430:<\/p>\n<p>  <\/p>\n<h4 id=\"shag-1---decompilerom-posmotret-na-kod-prisvoennyy-expressiont\">\u0428\u0430\u0433 1 \u2014 decompiler&#8217;\u043e\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043a\u043e\u0434 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043d\u044b\u0439 <code>Expression&lt;T&gt;<\/code><\/h4>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ox\/p3\/g2\/oxp3g2newr9bhr3oba5bajcrkco.png\"><\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0443\u0434\u0438\u0432\u0438\u0442 \u043f\u043e \u043f\u0435\u0440\u0432\u043e\u043c\u0443 \u0440\u0430\u0437\u0443. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043a\u0430\u043a \u0447\u0435\u0442\u044b\u0440\u044c\u043c\u044f \u043f\u0435\u0440\u0432\u044b\u043c\u0438 \u0441\u0442\u0440\u043e\u0447\u043a\u0430\u043c\u0438 \u0441\u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u0430\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">(\"sb\",\"t\") .. SerializeAssociativeArray..<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0441\u0432\u044f\u0437\u044c \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0443\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0418 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043e\u0441\u0432\u043e\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c (\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f &#8216;Expression.Const&#8217;, &#8216;Expression.Parameter&#8217;, &#8216;Expression.Call&#8217;, &#8216;Expression.Lambda&#8217; <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.linq.expressions.expression(v=vs.110).aspx\">etc<\/a> &#8230;) \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u0430\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u2014 \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u0445\u043e\u0434 \u0443\u0437\u043b\u043e\u0432 (\u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445). \u042d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c <em>eval \u0432 \u0421#<\/em>. <\/p>\n<p>  <\/p>\n<h4 id=\"shag-2----shodit-po-etoy-ssylkehttpsgithubcomdashboardcoderoutinesblobmastertestsconsoleappsclrmdautomationprogramcsl99-l194\">\u0428\u0430\u0433 2 \u2014 \u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u043e <a href=\"https:\/\/github.com\/DashboardCode\/Routines\/blob\/master\/Tests\/ConsoleApps\/ClrMdAutomation\/Program.cs#L99-L194\">\u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435<\/a>,<\/h4>\n<p>  <\/p>\n<p>\u0422\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440\u0430, \u043d\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u0412\u0442\u044f\u0433\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e \u0432\u044b\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u0431\u0438\u0441\u0435\u0440\u043e\u043c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0432\u0442\u043e\u0440\u0443 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430. \u0412\u0441\u0435 \u044d\u0442\u0438 \u0445\u0443\u0434\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 <a href=\"https:\/\/www.nuget.org\/packages\/DashboardCode.Routines\/\">\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/a>. \u0412\u0430\u0436\u043d\u043e \u0443\u0441\u0432\u043e\u0438\u0442\u044c \u0438\u0434\u0435\u044e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0421# (\u0438 .NET Standard).<\/p>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0433\u043e\u043d\u044f\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0435\u0441\u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u0435\u0440\u0435\u0434 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 (\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0430\u044f\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 <code>ComposeFormatter<\/code> \u2014 \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f), \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">static Func&lt;Point, string&gt; formatter = JsonManager.ComposeFormatter&lt;Point&gt;(); public string Get(Point p){    \/\/ which has better performance ?    var json1 = JsonConvert.SerializeObject(p);     var json2 = formatter(p);    return json2; } <\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">static CachedFormatter cachedFormatter  = new CachedFormatter(); public string Get(List&lt;Point&gt; list){    \/\/ there json formatter will be build only for first call     \/\/ and assigned to cachedFormatter.Formatter    \/\/ in all next calls cachedFormatter.Formatter will be used.    \/\/ since building of formatter is determenistic it is lock free     var json3 = list.Select(e=&gt; {X:e.X, Sum:e.X+E.Y})                          .ToJson(cachedFormatter, e=&gt;e.Sum);     return json3; } <\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e \u0437\u0430\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u043f\u0435\u0440\u0432\u0443\u044e \u043c\u0438\u043a\u0440\u043e\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0435\u043c, \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0435\u043c, \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0435\u043c\u2026 \u041a\u043e\u043c\u0443 \u0448\u0443\u0442\u043a\u0430, \u043a\u043e\u043c\u0443 \u043d\u0435\u0442, \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0432\u043e\u043f\u0440\u043e\u0441\u0443 \u0447\u0442\u043e \u043d\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440 \u0443\u043c\u0435\u0435\u0442 \u043d\u043e\u0432\u043e\u0433\u043e \u2014 \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u044e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u2014 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435. <\/p>\n<p>  <\/p>\n<h2 id=\"chto-vzamen\">\u0427\u0442\u043e \u0432\u0437\u0430\u043c\u0435\u043d?<\/h2>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u043e\u0442\u043e\u0440 DSL Includes \u0432 serilize (\u0430 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u044b equals, copy, clone \u2014 \u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0435\u0442) \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444:<\/p>\n<p>  <\/p>\n<p><strong>1\u044b\u0439 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444<\/strong> \u2014 \u043d\u0443\u0436\u043d\u0430 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444 \u0432\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u043a \u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Expression Trees \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 \u2014 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440 \u0438 \u043d\u0430 &#171;\u0440\u0435\u0444\u043b\u0435\u043a\u0448\u043d\u0430\u0445&#187; \u0438 \u0434\u0430\u0436\u0435 \u0432\u044b\u043b\u0438\u0437\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043e\u043d \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0441\u044f \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043a \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440\u0430\u043c (\u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 copy, clone \u0438 equals \u0438 \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 expression trees, \u0434\u0430 \u0438 \u043d\u0435 \u0432\u044b\u043b\u0438\u0437\u044b\u0432\u0430\u043b\u0438\u0441\u044c, \u0437\u0430\u0434\u0430\u0447\u0438 \u0442\u0430\u043a\u043e\u0439 \u043d\u0435\u0442, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0438 \u043e\u0442 &#171;\u043e\u0431\u043e\u0433\u043d\u0430\u0442\u044c&#187; ServiceStack \u0438 Json.NET \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0432\u0441\u0435\u043c\u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 json \u2014 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f). <\/p>\n<p>  <\/p>\n<p><strong>2\u043e\u0439 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444<\/strong> \u2014 \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0443\u0442\u0435\u0447\u043a\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439 \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441\u0445\u043e\u0436\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443: \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0435 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f\u043c\u0438. <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Point \u0438 IEnumerable \u043d\u0443\u0436\u043d\u044b \u0434\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430  <\/p>\n<pre><code class=\"cs\">var formatter1 = JsonManager.ComposeFormatter&lt;Point&gt;(); var formatter2 = JsonManager.ComposeEnumerableFormatter&lt;Point&gt;(); \/\/ but not \/\/ var formatter2 = JsonManager.ComposeEnumerableFormatter&lt;List&lt;Point&gt;&gt;();<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043b\u0438: &#171;\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u0438 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435\/closure?&#187;. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0437\u043b\u0443 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0438\u043c\u044f (\u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435):<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">string DATEFORMAT= \"YYYY\"; var formatter3 = JsonManager.ComposeFormatter&lt;Record&gt;(           chain =&gt; chain                     .Include(i =&gt; i.RecordId)                     .Include(i =&gt; i.CreatedAt.ToString(DATEFORMAT) , \"CreatedAt\"); );<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0438\u043a\u0442\u0443\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 <code>ComposeFormatter<\/code>.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u044b\u043c \u0437\u043b\u043e\u043c. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044f \u0441\u0444\u0435\u0440\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f Internal DSL, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0438 \u0443\u0442\u0435\u0447\u043a\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 Internal DSL \u044d\u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0433\u043d\u0435\u0442\u0430\u0442\u044c, \u0442\u0443\u0442 \u043d\u0430\u0434\u043e \u0437\u0430\u043f\u0430\u0441\u0442\u0438\u0441\u044c \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0441\u043a\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0443\u0442\u0435\u0447\u043a\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u0432\u0430\u044e\u0442\u0441\u044f \u0437\u043d\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u0435\u0442\u0430\u043b\u0435\u0439 Internal DSL (<em>\u0447\u0435\u0433\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c?<\/em>) \u0438 \u0431\u043e\u0433\u0430\u0442\u0441\u0442\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e DSL \u0438 \u0435\u0433\u043e \u0438\u043d\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u0432 (<em>\u0447\u0442\u043e \u0432\u0437\u0430\u043c\u0435\u043d?<\/em>). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441: &#171;\u0441\u0442\u043e\u0438\u0442 \u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Internal DSL?&#187;, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437 \u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e DSL \u2014 \u043e \u0432\u0441\u0435\u0445 \u0435\u0433\u043e \u043c\u0435\u043b\u043e\u0447\u0430\u0445 \u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430\u0445, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f (\u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430\u0445), \u0442.\u0435. \u0440\u0430\u0441\u0441\u043a\u0430\u0437 \u043e \u043f\u0440\u0435\u043e\u0434\u043e\u043b\u0435\u043d\u0438\u0438 \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444. <\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u044f \u0432\u0441\u0435 \u044d\u0442\u043e \u0432\u0432\u0438\u0434\u0443, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0441\u044c \u043a \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e DSL Includes.<\/p>\n<p>  <\/p>\n<p>\u0417\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0446\u0435\u043b\u044c\u044e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u043d\u0430 \u0442\u0440\u043e\u0439\u043a\u0438 (DTO, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0432 DTO, \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f DTO) \u043e\u0434\u043d\u043e\u0439 \u043f\u043e \u043c\u0435\u0441\u0442\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043f\u0440\u043e\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0412 \u043a\u043e\u043d\u0446\u0435-\u043a\u043e\u043d\u0446\u0435\u0432 \u0434\u0443\u0430\u043b\u0438\u0437\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f-\u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c &#171;DTO \u044d\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f&#187; \u0438 \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0446\u0435\u043b\u044c: \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c DTO \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. <\/p>\n<p>  <\/p>\n<p>\u0421\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0414\u0435\u0440\u0435\u0432\u043e\u043c \u043e\u0431\u0445\u043e\u0434\u0430 (\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0443\u0437\u043b\u044b \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043a\u0441\u0442\u0430\u0442\u0438 \u044d\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0446\u0438\u0440\u043a\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0441\u0441\u044b\u043b\u043e\u043a), \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043b\u0438\u0441\u0442\u044c\u0435\u0432 \u2014 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442\u0442\u0435\u0440 (\u043f\u043e \u0442\u0438\u043f\u0443).<\/li>\n<li>\u041f\u0440\u0430\u0432\u0438\u043b\u043e\u043c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043b\u0438\u0441\u0442\u044c\u0435\u0432 (\u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u0437\u0430\u0434\u0430\u043d\u044b) \u2014 property vs fields? readonly?<\/li>\n<li>\u0418\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0442\u044c \u043a\u0430\u043a \u0432\u0435\u0442\u043a\u0443 (\u0443\u0437\u0435\u043b \u0441 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0435\u0439) \u0442\u0430\u043a \u0438 \u043b\u0438\u0441\u0442 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e MemberExpression (<code>e=&gt;e.Name<\/code>), \u0430 \u0432\u043e\u043e\u0431\u0449\u0435 \u043b\u044e\u0431\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 (`e=&gt;e.Name.ToUpper(), &#171;MyMemberName&#187;) \u2014 \u0437\u0430\u0434\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442\u0442\u0435\u0440 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0443\u0437\u043b\u0443.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0414\u0440\u0443\u0433\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043b\u0443\u0436\u0430\u0449\u0438\u0435 \u0443\u0432\u0435\u043b\u0435\u0447\u0435\u043d\u0438\u044e \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0441\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0441\u0442\u0440\u043a\u0443 json &#171;as is&#187; (\u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442\u0442\u0435\u0440 \u0441\u0442\u0440\u043e\u043a);<\/li>\n<li>\u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442\u0442\u0435\u0440\u044b \u0433\u0440\u0443\u043f\u043f\u0430\u043c, \u0442.\u0435. \u0446\u0435\u043b\u044b\u043c \u0432\u0435\u0442\u043a\u0430\u043c, \u0432 \u044d\u0442\u043e\u0439 \u0432\u0435\u0442\u043a\u0435 \u0442\u0430\u043a \u2014 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e \u0434\u0440\u0443\u0433\u043e\u043c\u0443 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0443\u0442 \u0434\u0430\u0442\u044b \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c, \u0430 \u0432 \u044d\u0442\u043e\u0439 \u0431\u0435\u0437 \u0432\u0440\u0435\u043c\u0435\u043d\u0438).<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0412\u0435\u0437\u0434\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0443\u044e\u0442 \u0442\u0430\u043a\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043a\u0430\u043a: \u0434\u0435\u0440\u0435\u0432\u043e \u043e\u0431\u0445\u043e\u0434\u0430, \u0432\u0435\u0442\u043a\u0430, \u043b\u0438\u0441\u0442, \u0438 \u044d\u0442\u043e \u0432\u0441\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f DSL Includes.<\/p>\n<p>  <\/p>\n<h2 id=\"dsl-includes\">DSL Includes<\/h2>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0441\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441 EF Core \u2014 c\u043c\u044b\u0441\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 (\u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e xpath).<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\"> \/\/ DSL Includes Include&lt;User&gt; include1 = chain=&gt; chain    .IncludeAll(e =&gt; e.Groups)    .IncludeAll(e =&gt; e.Roles)        .ThenIncludeAll(e =&gt; e.Privileges)  \/\/ EF Core syntax \/\/ https:\/\/docs.microsoft.com\/en-us\/ef\/core\/querying\/related-data var users = context.Users    .Include(blog =&gt; blog.Groups)    .Include(blog =&gt; blog.Roles)       .ThenInclude(blog =&gt; blog.Privileges);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0443\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u0443\u0437\u043b\u044b &#171;\u0441 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0435\u0439&#187; \u2014 &#171;\u0432\u0435\u0442\u043a\u0438&#187;.<br \/>  \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441 \u043a\u0430\u043a\u0438\u0435 \u0443\u0437\u043b\u044b &#171;\u043b\u0438\u0441\u0442\u044c\u044f&#187; (\u043f\u043e\u043b\u044f\/\u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430) \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u0430\u043a \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u2014 \u043d\u0438\u043a\u0430\u043a\u0438\u0435. \u0427\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043b\u0438\u0441\u0442\u044c\u044f \u0438\u0445 \u043d\u0430\u0434\u043e \u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u044f\u0432\u043d\u043e:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include2 = chain=&gt; chain    .Include(e =&gt; e.UserName) \/\/ leaf member    .IncludeAll(e =&gt; e.Groups)       .ThenInclude(e =&gt; e.GroupName) \/\/ leaf member    .IncludeAll(e =&gt; e.Roles)       .ThenInclude(e =&gt; e.RoleName) \/\/ leaf member    .IncludeAll(e =&gt; e.Roles)       .ThenIncludeAll(e =&gt; e.Privileges)            .ThenInclude(e =&gt; e.PrivilegeName) \/\/ leaf member <\/code><\/pre>\n<p>  <\/p>\n<p>\u041b\u0438\u0431\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0443, \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0440\u0435\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">\/\/ Func&lt;ChainNode, MemberInfo&gt; rule = ... var include2 = IncludeExtensions.AppendLeafs(include1, rule); <\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0443\u0442 rule -\u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e ChainNode.Type \u0442.\u0435. \u043f\u043e \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0443\u0437\u043b\u043e\u043c (ChainNode \u2014 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 DSL Includes, \u043e \u0447\u0435\u043c \u0435\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0430\u0437\u0430\u043d\u043e) \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 (MemberInfo) \u0434\u043b\u044f \u0443\u0447\u0430\u0441\u0442\u0438\u044f \u0432 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440. \u0442\u043e\u043b\u044c\u043a\u043e property, \u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e read\/write property, \u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e, \u0442\u0435 \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u0444\u043e\u0440\u043c\u0430\u0442\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0442\u0438\u043f\u043e\u0432, \u0438 \u0434\u0430\u0436\u0435 \u0441\u0430\u043c\u043e include \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e (\u0435\u0441\u043b\u0438 \u0432 \u043d\u0435\u043c \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u0443\u0437\u043b\u044b-\u043b\u0438\u0441\u0442\u044c\u044f \u2014 \u0442.\u0435. \u0444\u043e\u0440\u043c\u0430 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432). <\/p>\n<p>  <\/p>\n<p>\u041b\u0438\u0431\u043e\u2026 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c\u0443 \u0438\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0430\u043c \u0440\u0435\u0448\u0430\u0435\u0442 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u0443\u0437\u043b\u0430\u043c\u0438. DSL Includes \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u043a\u0430\u043a \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u043f\u0438\u0441\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0440\u0442\u0430\u0442\u043e\u0440\u0430. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u043a \u0435\u043c\u0443 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u043f\u043b\u043e\u0442\u044c \u0434\u043e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0425\u043e\u0440\u043e\u0448\u0438\u0439 Internal DSL \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d \u043d\u0430 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0440\u0442\u0430\u0442\u043e\u0440\u043e\u0432, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<br \/>  \u041e\u0434\u043d\u0438 \u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0440\u0442\u0430\u0442\u043e\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u0430\u043c\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0438\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c (\u0447\u0435\u0440\u0435\u0437 Expression Tree, \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 Reflection.Emit). \u041a\u043e\u0434 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Internal DSL \u0431\u0443\u0434\u0435\u0442 \u0441\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0434\u043e \u043d\u0435\u0433\u043e.<\/p>\n<p>  <\/p>\n<h4 id=\"out-of-the-box\">Out of the box<\/h4>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 EF Core.<br \/>  \u0425\u043e\u0434\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 &#171;\u043e\u0442\u0440\u0443\u0431\u0438\u0442\u044c \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0441\u0441\u044b\u043b\u043a\u0438&#187;, \u0432 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u043d\u043e \u0432 include-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">static CachedFormatter cachedFormatter1 = new CachedFormatter();     string GetJson()     {            using (var dbContext = GetEfCoreContext())            {                  string json =                   EfCoreExtensions.ToJsonEf&lt;User&gt;(cachedFormatter1, dbContext, chain=&gt;chain                               .IncludeAll(e =&gt; e.Roles)                               .ThenIncludeAll(e =&gt; e.Privileges));            }     }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0443 <code>ToJsonEf<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043f\u0440\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0435\u0435 \u0436\u0435 (\u043e\u0442\u0431\u0438\u0440\u0430\u0435\u0442 \u043b\u0438\u0441\u0442\u044c\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u043c &#171;\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f EF Core&#187;, \u0442.\u0435. public read\/write property), \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442\u0441\u044f \u0443 \u043c\u043e\u0434\u0435\u043b\u0438 \u2014 \u0433\u0434\u0435 string\/json \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c as is, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442\u0442\u0435\u0440\u044b \u043f\u043e\u043b\u0435\u0439 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (byte[] \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, datetime \u0432 ISO \u0438 \u0442.\u043f). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c IQuaryable \u0438\u0437 \u043f\u043e\u0434 \u0441\u0435\u0431\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u2014 \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c DSL Includes \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 (\u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440, \u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043c\u0435\u0441\u0442\u0443: <\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">static CachedFormatter cachedFormatter1 = new CachedFormatter(); string GetJson() {            using (var dbContext = GetEfCoreContext())            {                  var json = dbContext.ParentRecords                            \/\/ back to EF core includes                            \/\/ but .Include(include1) also possible                               .IncludeAll(e =&gt; e.Roles)                               .ThenIncludeAll(e =&gt; e.Privileges)                     .Select(e =&gt; new { FieldA: e.FieldA, FieldJson:\"[1,2,3]\", Role: e.Roles().First() })                    .ToJson(cachedFormatter1,                            chain =&gt; chain.Include(e =&gt; e.Role),                           LeafRuleManager.DefaultEfCore,                           config:  rules =&gt; rules                                .AddRule&lt;string[]&gt;(GetStringArrayFormatter)                                .SubTree(                                       chain  =&gt; chain.Include(e =&gt; e.FieldJson),                                       stringAsJsonLiteral: true) \/\/ json as is                                .SubTree(                                       chain  =&gt; chain.Include(e =&gt; e.Role),                                       subRules =&gt; subRules                                                    .AddRule&lt;DateTime&gt;(                                                          dateTimeFormat: \"YYYMMDD\",                                                           floatingPointFormat: \"N2\"                                         )                     ),                     ),                 useToString: false, \/\/ no default ToString for unknown leaf type (throw exception)                 dateTimeFormat: \"YYMMDD\",                  floatingPointFormat: \"N2\"            } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0432\u0441\u0435 \u044d\u0442\u0438 \u0434\u0435\u0442\u0430\u043b\u0438, \u0432\u0441\u0435 \u044d\u0442\u043e &#171;\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e&#187;, \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0434\u043e \u0438\/\u0438\u043b\u0438 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0442\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0440\u0442\u0430\u0442\u043e\u0440. \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444: DTO \u043d\u0435 \u0440\u0430\u0437\u043c\u0430\u0437\u0430\u043d \u043f\u043e \u043a\u043e\u0434\u0443, \u0437\u0430\u0434\u0430\u043d \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u044b \u0443\u0432\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b. \u041a\u043e\u0434\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u0435\u043d\u044c\u0448\u0435 \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u043e. <\/p>\n<p>  <\/p>\n<p><strong>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0438\u0442\u044c<\/strong>: \u0445\u043e\u0442\u044f \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b \u0432 ASP \u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432 \u043d\u0430\u043b\u0438\u0447\u0438\u0438, \u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043d\u0443\u0436\u043d\u0430\u044f \u0448\u0442\u0443\u043a\u0430 \u0432 \u043c\u0438\u0440\u0435 \u0432\u0435\u0431\u0430, \u0433\u0434\u0435 \u0434\u0430\u0436\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0434\u0430\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 json, \u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 DSL Includes \u0432 ASP MVC <a href=\"https:\/\/stackoverflow.com\/questions\/42360139\/asp-net-core-return-json-with-status-code\">\u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0435 \u0441\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f<\/a>. \u041a\u0430\u043a \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441 ASP MVC \u2014 \u0437\u0430\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0443\u0441\u044c \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u044f\u043c\u0438 \u0438\u043c\u0435\u043d\u043d\u043e DSL Includes, \u0431\u0443\u0434\u0443 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438 \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0438 \u0443\u0442\u0435\u0447\u043a\u0443 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439, \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 &#171;\u0442\u0440\u0435\u0439\u0434\u043e\u0444\u0444&#187; \u0432\u043e\u043e\u0431\u0449\u0435-\u0442\u043e \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u0435\u043c\u0430.<\/p>\n<p>  <\/p>\n<h2 id=\"esche-bolshe-dsl-includes\">\u0415\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 DSL Includes<\/h2>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;Point&gt; include = chain =&gt; chain.Include(e=&gt;e.X).Include(e=&gt;e.Y);<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 EF \u0421ore Includes \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u0421\u0430\u043c DSL Includes \u0440\u043e\u0434\u0438\u043b\u0441\u044f \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c &#171;include&#187; \u0432 \u043c\u043e\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0448\u0430\u0431\u043b\u043e\u043d\u0430 Repository \u0431\u0435\u0437 \u0434\u0435\u0433\u0440\u0430\u0434\u0430\u0446\u0438\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0442\u0438\u043f\u0430\u0445 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043f\u0440\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0438\u0445 \u0432 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u043e\u0435 \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0432\u0441\u0435 \u0436\u0435 \u0432 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0438. EF Core Includes \u2014 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 (\u0443\u0437\u043b\u043e\u0432 \u0432\u0435\u0442\u043e\u043a), DSL Includes \u2014 \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0431\u0445\u043e\u0434\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u0438\u043c\u0435\u043d\u0438 (path) \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 EF Core Includes \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0442\u0440\u043e\u043a \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 MemberExpression.Member (Expression \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u0430\u044f <code>e=&gt;User.Name<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e [MemberExpression](<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.linq.expressions.memberexpression(v=vs.110).aspx\">https:\/\/msdn.microsoft.com\/en-us\/library\/system.linq.expressions.memberexpression(v=vs.110).aspx<\/a> \u0430 \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u0447\u043a\u0430 <code>Name<\/code>). <\/p>\n<p>  <\/p>\n<p>\u0412 DSL Includes \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u2014 \u043a\u043b\u0430\u0441\u0441\u044b <a href=\"https:\/\/github.com\/DashboardCode\/Routines\/blob\/master\/Routines\/ChainNode.cs\">ChainNode \u0438 ChainMemberNode<\/a> \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0449\u0435\u0435 expression (e.g. <code>e=&gt;User.Name<\/code>)\u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u0435, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043e \u0432 Expression Tree. \u0418\u043c\u0435\u043d\u043d\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438 \u0442\u043e \u0447\u0442\u043e DSL Includes \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0438 \u043f\u043e\u043b\u044f \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 value types \u0438 \u0432\u044b\u0437\u043e\u0432\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 :<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include = chain =&gt; chain                     .Include(i =&gt; i.UserName)                     .Include(i =&gt; i.Email.ToUpper(),\"EAddress\");<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0441 \u044d\u0442\u0438\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430. CreateFormatter- \u0432\u044b\u0434\u0430\u0441\u0442 {&#171;UserName&#187;:&#187;John&#187;, &#171;EAddress&#187;:&#187;JOHN@MAIL.COM&#187;} <\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u043f\u043e nullable \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;StrangePointF&gt; include     = chain =&gt; chain          .Include(e =&gt; e.NextPoint) \/\/ NextPoint is nullable struct              .ThenIncluding(e =&gt; e.Value.X)              .ThenInclude(e =&gt; e.Value.Y);  \/\/ but not this way (abstraction leak) \/\/            Include&lt;StrangePointF&gt; include \/\/                = chain =&gt; chain                        \/\/ now this can throw an exception \/\/                    .Include(e =&gt; e.NextPoint.Value)   \/\/                        .ThenIncluding(e =&gt; e.X)  \/\/                        .ThenInclude(e =&gt; e.Y);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 DSL Includes \u0442\u0430\u043a \u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043e\u0440\u043e\u0442\u043a\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0430 ThenIncluding .<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include = chain =&gt; chain     .Include(i =&gt; i.UserName)     .IncludeAll(i =&gt; i.Groups)            \/\/  ING-form - doesn't change current node           .ThenIncluding(e =&gt; e.GroupName)   \/\/ leaf           .ThenIncluding(e =&gt; e.GroupDescription)  \/\/ leaf           .ThenInclude(e =&gt; e.AdGroup); \/\/ leaf<\/code><\/pre>\n<p>  <\/p>\n<p>\u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435 \u0441 <\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include = chain =&gt; chain       .Include(i =&gt; i.UserName)       .IncludeAll(i =&gt; i.Groups)             .ThenInclude(e =&gt; e.GroupName)        .IncludeAll(i =&gt; i.Groups)             .ThenInclude(e =&gt; e.GroupDescription)        .IncludeAll(i =&gt; i.Groups)             .ThenInclude(e =&gt; e.AdGroup);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u0443\u0442\u0435\u0447\u043a\u0430 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u044f \u0437\u0430\u043f\u0438\u0441\u0430\u043b \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u043e\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e, \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0442\u0430\u0442\u043e\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c QuaryableExtensions. \u0410 \u043e\u043d \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0432\u044b\u0437\u043e\u0432\u044b Include \u0438 ThenInclude \u0432 Include &#171;\u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439&#187;. \u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043d\u0430\u0434\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u0432\u0438\u0434\u0443). <\/p>\n<p>  <\/p>\n<p><strong>\u0410\u043b\u0433\u0435\u0431\u0440\u0430 Include \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/strong>.<\/p>\n<p>  <\/p>\n<p>Include-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">C\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">var b1 = InlcudeExtensions.IsEqualTo(include1, include2); var b2 = InlcudeExtensions.IsSubTreeOf(include1, include2); var b3 = InlcudeExtensions.IsSuperTreeOf(include1, include2);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">var include2 = InlcudeExtensions.Clone(include1);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0442\u044c (merge)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">var include3 = InlcudeExtensions.Merge(include1, include2);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u043f\u0438\u0441\u043a\u0438 XPath &#8212; \u0432\u0441\u0435 \u043f\u0443\u0442\u0438 \u0434\u043e \u043b\u0438\u0441\u0442\u044c\u0435\u0432<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">IReadOnlyCollection&lt;string&gt; paths1 = InlcudeExtensions.ListLeafXPaths(include); \/\/ as xpaths IReadOnlyCollection&lt;string[]&gt; paths2 = InlcudeExtensions.ListLeafKeyPaths(include); \/\/  as string[]<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u0438 \u0442.\u043f.<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0430\u044f \u043d\u043e\u0432\u043e\u0441\u0442\u044c: \u0442\u0443\u0442 \u043d\u0435\u0442 \u0443\u0442\u0435\u0447\u0435\u043a \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0439, \u0442\u0443\u0442 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0447\u0438\u0441\u0442\u043e\u0439 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438. \u0415\u0441\u0442\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438. <\/p>\n<p>  <\/p>\n<h2 id=\"dialektika\">\u0414\u0438\u0430\u043b\u0435\u043a\u0442\u0438\u043a\u0430<\/h2>\n<p>  <\/p>\n<p>DSL Includes \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u043d\u043e\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043d\u043e \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c: \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u0438 Include \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c DSL \u043a\u0430\u043a \u0446\u0435\u043f\u043e\u0447\u043a\u0438 fluent \u2014 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0435\u0442, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">var root = new ChainNode(typeof(Point)); var child = new ChainPropertyNode(          typeof(int),          expression: typeof(Point).CreatePropertyLambda(\"X\"),          memberName:\"X\", isEnumerable:false, parent:root ); root.Children.Add(\"X\", child); \/\/ or there is number of extension methods e.g.: var child = root.AddChild(\"X\");  Include&lt;Point&gt; include = ChainNodeExtensions.ComposeInclude&lt;Point&gt;(root);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u044b \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0417\u0430\u0447\u0435\u043c \u0436\u0435 \u0442\u043e\u0433\u0434\u0430 fluent \u0437\u0430\u043f\u0438\u0441\u044c DSL includes \u0432\u043e\u043e\u0431\u0449\u0435? \u042d\u0442\u043e \u0447\u0438\u0441\u0442\u043e \u0443\u043c\u043e\u0437\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439: \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u2014 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 (\u0430 \u043e\u043d\u043e \u0442\u043e\u0436\u0435 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f) \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435\u043c DSL (\u0442.\u0435. \u043a\u0440\u0430\u0442\u043a\u043e\u0439 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u0434\u0430). \u0415\u0449\u0435 \u0440\u0430\u0437 \u043e\u0431 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0431\u043b\u0438\u0436\u0435 \u043a \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<h2 id=\"copy-clone-equals\">Copy, Clone, Equals<\/h2>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0441\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0432\u0435\u0440\u043d\u043e \u0438 \u043f\u0440\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u044b include-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0435 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u044b <strong>copy<\/strong>, <strong>clone<\/strong>, <strong>equals<\/strong>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Equals<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043b\u0438\u0441\u0442\u044c\u044f\u043c \u0438\u0437 Include-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<br \/>  \u0421\u043a\u0440\u044b\u0442\u0430\u044f \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043d\u0435\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0432 \u0441\u043f\u0438\u0441\u043a\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include = chain=&gt;chain.Include(e=&gt;e.UserId).IncludeAll(e=&gt;e.Groups).ThenInclude(e=&gt;e.GroupId)  bool b1 = ObjectExtensions.Equals(user1, user2, include); bool b2 = ObjectExtensions.EqualsAll(userList1, userList2, include);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Clone<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u043e\u0445\u043e\u0434 \u043f\u043e \u0443\u0437\u043b\u0430\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include = chain=&gt;chain.Include(e=&gt;e.UserId).IncludeAll(e=&gt;e.Groups).ThenInclude(e=&gt;e.GroupId)  var newUser = ObjectExtensions.Clone(user1, include, leafRule1); var newUserList = ObjectExtensions.CloneAll(userList1, leafRule1);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0440\u0435\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0431\u0438\u0440\u0430\u0442\u044c leaf \u0438\u0437 includes. \u041f\u043e\u0447\u0435\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u2014 \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e? \u0427\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0445\u043e\u0436\u0435 \u0441 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u043e\u0439 ObjectExtensions.Copy<\/p>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Copy<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u043e\u0445\u043e\u0434 \u043f\u043e \u0443\u0437\u043b\u0430\u043c-\u0432\u0435\u0442\u043a\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e \u0443\u0437\u043b\u0430\u043c-\u043b\u0438\u0441\u0442\u044c\u044f\u043c. \u041a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u043e (\u0441\u0445\u043e\u0436\u0435 \u0441 Clone).<\/p>\n<p>  <\/p>\n<pre><code class=\"cs\">Include&lt;User&gt; include = chain=&gt;chain.IncludeAll(e=&gt;e.Groups);  ObjectExtensions.Copy(user1, user2, include, supportedLeafsRule);   ObjectExtensions.CopyAll(userList1, userList2, include, supportedLeafsRule);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0431\u0438\u0440\u0430\u0442\u044c leaf \u0438\u0437 includes. \u041f\u043e\u0447\u0435\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u2014 \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e? \u0427\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0445\u043e\u0436\u0435 \u0441 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 ObjectExtensions.Copy (\u0442\u0430\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u043e \u2014 \u0432 include \u0442\u043e \u043a\u0430\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c, \u0432 supportedLeafsRule \u2014 \u0442\u043e \u0447\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c).<\/p>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u0414\u043b\u044f copy \/ clone \u043d\u0430\u0434\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u0432\u0438\u0434\u0443: <\/p>\n<p>  <\/p>\n<ol>\n<li>\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c readonly \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430, \u043f\u0440\u0438\u0447\u0435\u043c \u044d\u0442\u043e \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0442\u0438\u043f\u044b Tuple&lt;,&gt; \u0438 Anonymous Type. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u0438\u043c \u0443\u0433\u043b\u043e\u043c. <\/li>\n<li>\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u0442\u0438\u043f (\u043d\u0430\u043f\u0440. IEnumerable \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c) \u2014 \u043a\u0430\u043a\u0438\u043c public \u0442\u0438\u043f\u043e\u043c \u0435\u0433\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c.<\/li>\n<li>\u0412\u0441\u0435 expression \u0438\u0437 include-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0432\u044b\u0440\u0430\u0436\u0430\u044e\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u043f\u043e\u043b\u044f \u2014 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0431\u0440\u043e\u0448\u0435\u043d\u044b.<\/li>\n<li>&#171;\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432&#187; \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435.<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0410\u0432\u0442\u043e\u0440 DSL \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0442\u043e \u0447\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0432\u044b\u0442\u0435\u043a\u0430\u044e\u0449\u0438\u0435 \u0438\u0437 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0430 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438 \u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u0442\u044c, \u0442.\u0435. \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442 \u0447\u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 \u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u044b. \u041a\u0441\u0442\u0430\u0442\u0438, \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0445 \u0438 <code>Tuple&lt;,&gt;<\/code>, \u0442.\u0435. \u0442\u0438\u043f\u043e\u0432 c readonly \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438, \u0438\u043b\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 <code>ValueTuple&lt;,&gt;<\/code> c writabale \u043f\u043e\u043b\u044f\u043c\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u043c\u0438 (\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043a\u0430\u043a \u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c).<\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0430\u044f \u043d\u043e\u0432\u043e\u0441\u0442\u044c, \u0437\u0434\u0435\u0441\u044c \u0432 \u0442\u043e\u043c \u0447\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 (\u043d\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0443\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e Expression Trees) Includes \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u2014 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u0412\u0441\u044f \u0430\u043b\u0433\u0435\u0431\u0440\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Include DSL \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430. <\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u0432 Detach, FindDifferences \u0438 \u0442.\u043f.<\/p>\n<p>  <\/p>\n<h2 id=\"pochemu-run-time-a-ne-cs-sgenerirovannyy-do-nachala-kompilyacii\">\u041f\u043e\u0447\u0435\u043c\u0443 run-time, \u0430 \u043d\u0435 .cs \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0434\u043e \u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438?<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c .cs \u044d\u0442\u043e \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u0443 <em>run-time<\/em> \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430: <\/p>\n<p>  <\/p>\n<ol>\n<li>\u0418\u0437\u0431\u0435\u0433\u0430\u0435\u043c \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u043e\u0439 \u0432\u043e\u0437\u043d\u0438 \u0441\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430\u043c\u0438 (\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u043e\u0432, \u0438\u043c\u0435\u043d \u0444\u0430\u0439\u043b\u043e\u0432, source control). <\/li>\n<li>\u0418\u0437\u0431\u0435\u0433\u0430\u0435\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u043a \u0441\u0440\u0435\u0434\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u043c, \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u044f\u0437\u044b\u043a\u0430\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u2014 \u0432\u0441\u0435 \u0447\u0442\u043e \u043f\u043e\u0432\u044b\u0448\u0430\u0435\u0442 \u043f\u043e\u0440\u043e\u0433 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f. <\/li>\n<li>\u0418\u0437\u0431\u0435\u0433\u0430\u0435\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b &#171;\u044f\u0439\u0446\u0430 \u0438 \u043a\u0443\u0440\u0438\u0446\u044b&#187;. \u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f dev time \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0441\u0442\u0438, \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e: &#171;\u0410&#187; \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e &#171;\u0411&#187; \u0435\u0449\u0435 \u043d\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u0430 &#171;\u0411&#187; \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d, \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e &#171;\u0410&#187; \u0435\u0449\u0435 \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d. <\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0440\u0435\u0448\u0430\u0435\u043c\u043e Roslyn&#8217;\u043e\u043c, \u043d\u043e \u0438 \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043d\u043e\u0441\u0438\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0440\u043e\u0433 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f. \u0412\u043f\u0440\u043e\u0447\u0435\u043c \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u044b Typescript \u0431\u0438\u043d\u0434\u0438\u0433\u0438 (\u044f \u0436\u0435 DTO \u0437\u0430\u043f\u0438\u0441\u0430\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u0442.\u0435. \u0442\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430) \u2014 \u043d\u0430\u0434\u043e \u0432\u044b\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c DSL Includes \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f Roslyn&#8217;\u043e\u043c (\u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c) \u2014 \u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043d\u0442\u0440\u0435\u0440\u043f\u0440\u0435\u0442\u043e\u0440 \u0438\u0445 \u0432 typescript (\u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0447\u0430\u0441\u0442\u044c). \u0422\u043e\u0433\u0434\u0430 &#171;\u0437\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044e&#187; \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438 &#171;\u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440&#187; \u0432 .cs (\u0430 \u043d\u0435 \u0432 Expression Trees).<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u044b\u0442\u043e\u0436\u0443: \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0436\u0435 run time \u2014 \u043f\u043e\u0447\u0442\u0438 \u0447\u0438\u0441\u0442\u0430\u044f \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f, \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u041f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0434\u043e \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c (\u0438 \u0441\u043e\u0433\u043b\u0430\u0448\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0434\u0438\u043a\u0443\u044e \u043f\u043e \u043e\u0431\u044a\u0435\u043c\u0443 \u0437\u043d\u0430\u043a\u043e\u0432 \u0437\u0430\u043f\u0438\u0441\u044c Expression Trees). <\/p>\n<p>  <\/p>\n<h2 id=\"problemy-s-effektivnostyu-skompilirovannyh-funkciy-expression-trees\">\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 Expression Trees<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 Internal DSL \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Expression Tree \u043d\u0430\u0434\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u0432\u0438\u0434\u0443 \u0447\u0442\u043e:<\/p>\n<p>  <\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.linq.expressions.lambdaexpression.compile(v=vs.110).aspx\"><code>LambdaExpression.Compile<\/code><\/a> \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0445\u043d\u044e\u044e <em>Lambda<\/em>. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0447\u0438\u043c, \u043d\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c. \u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0434\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u043b\u044f\u043c\u0431\u0434\u0430, \u043f\u043e \u0445\u043e\u0434\u0443 &#171;\u0441\u043a\u043b\u0435\u0439\u043a\u0438&#187; expression tree, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0432 CallExpression \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u2014 \u043d\u0435 LambdaExpression, \u0430 \u0434\u0435\u043b\u0435\u0433\u0430\u0442 (\u0442.\u0435 \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 LambdaExpression) \u0437\u0430\u0432\u0435\u0440\u043d\u0443\u0442\u044b\u0439 \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 ConstantExpression.<\/p>\n<p>  <\/li>\n<li>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 <em>\u0430ss\u0435mbly<\/em>, \u0438 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 (\u0432 10 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434 \u0432 \u043c\u043e\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445) \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c (\u043c\u043e\u0438 assembly \u043d\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u044b \u2014 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u043b\u044c\u0448\u0435). \u041e\u043d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043d\u0435 \u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0435\u0441\u043b\u0438 \u0441\u0438\u043b\u044c\u043d\u043e \u0434\u0440\u043e\u0431\u0438\u0442\u044c \u043a\u043e\u0434 \u2014 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043d\u0443\u044e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 (\u0432 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u0439 \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0438), \u0447\u0442\u043e \u044f \u043f\u043e\u043a\u0430 \u043d\u0435 \u043c\u043e\u0433\u0443, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0435 \u0438\u043c\u0435\u044e \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0434\u0435\u0442\u0430\u043b\u0435\u0439. \u041d\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u044b\u0445\u043e\u0434: \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u0445 \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u0445. \u0418 \u043a\u0441\u0442\u0430\u0442\u0438 \u2014 \u0434\u0430 \u2014 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0432 .cs \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0431\u044b \u0441\u043d\u044f\u043b\u0430.<\/p>\n<p>  <\/p>\n<h2 id=\"benchmark-serializacii\">\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u2014 \u041e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 600 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043d\u0430 15 \u043f\u043e\u043b\u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u041f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c JSON.NET, ServiceStack \u043d\u0443\u0436\u043d\u043e \u0434\u0432\u0430 \u0432\u044b\u0437\u043e\u0432\u0430 reflection&#8217;\u0430 GetProperties().<\/p>\n<p>  <\/p>\n<p>dslComposeFormatter \u2014 ComposeFormatter \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 <a href=\"https:\/\/github.com\/DashboardCode\/Routines\/blob\/master\/Tests\/Benchmark\/BenchmarkComposeFormatter.cs\">\u0437\u0434\u0435\u0441\u044c<\/a> .<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/benchmarkdotnet.org\/articles\/overview.html\">BenchmarkDotNet<\/a>=v0.10.14, OS=Windows 10.0.17134<br \/>  Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), 1 CPU, 4 logical and 4 physical cores<br \/>  .NET Core SDK=2.1.300<\/p>\n<p>  <\/p>\n<table>\n<thead>\n<tr>\n<th>Method<\/th>\n<th>Mean<\/th>\n<th>Error<\/th>\n<th>StdDev<\/th>\n<th>Min<\/th>\n<th>Max<\/th>\n<th>Median<\/th>\n<th>Allocated<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>dslComposeFormatter<\/td>\n<td>2.208 ms<\/td>\n<td>0.0093 ms<\/td>\n<td>0.0078 ms<\/td>\n<td>2.193 ms<\/td>\n<td>2.220 ms<\/td>\n<td>2.211 ms<\/td>\n<td>849.47 KB<\/td>\n<\/tr>\n<tr>\n<td>JsonNet_Default<\/td>\n<td>2.902 ms<\/td>\n<td>0.0160 ms<\/td>\n<td>0.0150 ms<\/td>\n<td>2.883 ms<\/td>\n<td>2.934 ms<\/td>\n<td>2.899 ms<\/td>\n<td>658.63 KB<\/td>\n<\/tr>\n<tr>\n<td>JsonNet_NullIgnore<\/td>\n<td>2.944 ms<\/td>\n<td>0.0089 ms<\/td>\n<td>0.0079 ms<\/td>\n<td>2.932 ms<\/td>\n<td>2.960 ms<\/td>\n<td>2.942 ms<\/td>\n<td>564.97 KB<\/td>\n<\/tr>\n<tr>\n<td>JsonNet_DateFormatFF<\/td>\n<td>3.480 ms<\/td>\n<td>0.0121 ms<\/td>\n<td>0.0113 ms<\/td>\n<td>3.458 ms<\/td>\n<td>3.497 ms<\/td>\n<td>3.479 ms<\/td>\n<td>757.41 KB<\/td>\n<\/tr>\n<tr>\n<td>JsonNet_DateFormatSS<\/td>\n<td>3.880 ms<\/td>\n<td>0.0139 ms<\/td>\n<td>0.0130 ms<\/td>\n<td>3.854 ms<\/td>\n<td>3.899 ms<\/td>\n<td>3.877 ms<\/td>\n<td>785.53 KB<\/td>\n<\/tr>\n<tr>\n<td>ServiceStack_SerializeToString<\/td>\n<td>4.225 ms<\/td>\n<td>0.0120 ms<\/td>\n<td>0.0106 ms<\/td>\n<td>4.201 ms<\/td>\n<td>4.243 ms<\/td>\n<td>4.226 ms<\/td>\n<td>805.13 KB<\/td>\n<\/tr>\n<tr>\n<td>fake_expressionManuallyConstruted<\/td>\n<td>54.396 ms<\/td>\n<td>0.1758 ms<\/td>\n<td>0.1644 ms<\/td>\n<td>54.104 ms<\/td>\n<td>54.629 ms<\/td>\n<td>54.383 ms<\/td>\n<td>7401.58 KB<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>  <\/p>\n<p>fake_expressionManuallyConstruted \u2014 expression \u0433\u0434\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0445\u043d\u044f\u044f \u043b\u044f\u043c\u0431\u0434\u0430 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0430 (\u0446\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438).<\/p>\n<p>  <\/p>\n<h2 id=\"formalizaciya\">\u0424\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u041a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0438 DSL \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: <strong>\u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e DSL \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0432 \u044f\u0437\u044b\u043a \u0441\u0440\u0435\u0434\u044b \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f; \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e Internal DSL \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f run-time<\/strong>. <\/p>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435\u043c \u0438\u0437 \u0437\u0430\u043a\u043e\u043d\u0430 &#171;\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 DSL&#187; \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e \u0447\u0442\u043e Expression Tree \u2014 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u0431\u0435\u0437\u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u043c\u0435\u0442\u044c <em>\u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e<\/em> \u043d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 .NET Standard \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Expression Trees \u0434\u043b\u044f <em>\u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 <\/em>\u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u0432\u044b\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u043c Internal DSL \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 fluent API. \u0422\u0430\u043a\u0438\u043c \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0421# \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u0432 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0438\u0434\u0442\u0438 \u043f\u0443\u0442\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f fluent \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043a\u043e\u0434\u0430 (\u0431\u0435\u0437 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c Expression Trees, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u044b\u043c \u0434\u043b\u044f Internal DSL \u0432 \u0421# \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0446\u0435\u043f\u043e\u0447\u0435\u043a fluent, \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c &#171;\u043d\u0435\u043c\u043d\u043e\u0436\u043a\u043e&#187; \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c Expression Trees). <\/p>\n<p>  <\/p>\n<p><strong>Expression Trees<\/strong> \u0432\u043d\u0443\u0442\u0440\u0438 <strong>DSL Includes<\/strong> \u0438\u0433\u0440\u0430\u044e\u0442 \u0440\u043e\u043b\u044c \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0443\u044e (\u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u0443\u0437\u043b\u043e\u0432, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0432 \u0440\u0443\u0447\u043d\u0443\u044e), \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0435\u0440\u0442\u0430\u0442\u043e\u0440\u0430\/\u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440\u0430 \u2014 \u0440\u0435\u0448\u0430\u044e\u0449\u0443\u044e. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c <strong>DSL Includes<\/strong> \u0438\u043c\u0435\u0435\u0442 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430: \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438- \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0441\u0432\u043e\u0439\u0441\u0442\u0432 <strong>serialize<\/strong>, <strong>copy<\/strong>, <strong>clone<\/strong>, <strong>equals<\/strong> \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u043c\u0443 \u0441\u043f\u043e\u0441\u043e\u0431\u0443 <strong>\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c &#171;\u043e\u0431\u0445\u043e\u0434\u0430&#187;<\/strong>. \u041d\u0430 \u044d\u0442\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439, \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u0441\u0430\u043c &#171;Internal DSL&#187;, \u0447\u0435\u0440\u0435\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0435\u0433\u043e &#171;\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f&#187;, \u0442.\u0435. \u0431\u0435\u0437 \u0437\u0430\u043f\u0438\u0441\u0438 fluent C#.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e &#171;\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f&#187;, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0442\u0432\u043e\u0440\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0442\u0430\u043a\u0438\u043c \u043f\u0443\u0442\u0435\u043c \u043d\u0435 \u0438\u0434\u0435\u0442. \u0423\u0434\u043e\u0431\u043d\u0430\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430: \u0430\u043b\u0433\u0435\u0431\u0440\u0430 includes \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u0430 (\u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044e) \u0447\u0435\u043c, \u0442\u0435 \u0436\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 (\u0445\u043e\u0442\u044f \u043e\u043d\u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b, \u043f\u043e \u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b).<\/p>\n<p>  <\/p>\n<h2 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 DSL Includes \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c DTO \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u0442\u0435\u043c \u0447\u0435\u043c \u043e\u043d\u043e \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u0432 json). \u0423\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0439\u0442\u0438 \u043d\u0430 \u043d\u043e\u0432\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0432, \u0430 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u044f \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043a\u0430\u043a \u0432 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0442\u0430\u043a \u0438 &#171;\u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u0434\u0430&#187;, \u043d\u043e \u0432\u0441\u0435 \u0436\u0435 \u0437\u0430 \u0441\u0447\u0435\u0442 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0420\u043e\u0441\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 = \u0440\u043e\u0441\u0442 \u0443\u0442\u0435\u0447\u0435\u043a \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438. <\/p>\n<p>  <\/p>\n<p>\u041e\u0442\u0432\u0435\u0442\u043e\u043c \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 Internal DSL \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430\u043c\u0438 DSL, \u043d\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f Internal DSL (\u0432 \u043a\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f Expression) \u0438 \u043d\u0430 \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u043d\u0438\u044f \u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430 (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0438\u043b\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e Expression Tree). <\/p>\n<p>  <\/p>\n<p>\u0418 DSL Includes \u0438 json \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 ComposeFormatter \u043b\u0435\u0436\u0430\u0442 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 <a href=\"https:\/\/www.nuget.org\/packages\/DashboardCode.Routines\/\">DashboardCodes.Routines<\/a> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 nuget \u0438 GitHub.<\/p>\n<\/div>\n<p>        <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <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\/post\/419759\/\"> https:\/\/habr.com\/post\/419759\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div data-io-article-url=\"https:\/\/habr.com\/post\/419759\/\" class=\"post__text post__text-html js-mediator-article\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/_c\/m3\/gr\/_cm3grewmg9yewpcch1nqkl2ho8.png\"><\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u0434\u0432\u043e\u0439\u043d\u043e\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044e API <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/expression-trees\/\">Expression Trees<\/a> \u2014 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430. \u0420\u0430\u0437\u0431\u043e\u0440 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f (\u043e\u043d\u0438 \u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 <a href=\"https:\/\/martinfowler.com\/books\/dsl.html\">Internal DSL<\/a>), \u0430 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u2014 \u043d\u0430\u0431\u043e\u0440\u044b \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<p>\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0443\u0434\u0443 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 <strong>\u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432: serialize, copy, clone, equals<\/strong>. \u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 serialize \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e (\u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430\u043c\u0438) \u0432 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 &#171;\u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435&#187; \u0437\u043d\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0418\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0430\u0439\u0437\u0435\u0440\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0435\u0442 &#171;\u043d\u0435\u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u044e\u0449\u0435\u0439 \u043a\u0430\u043a\u0438\u0435 \u0443\u0437\u043b\u044b \u0434\u0435\u0440\u0435\u0432\u0430 \u043d\u0430\u0434\u043e \u043e\u0431\u043e\u0439\u0442\u0438, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 &#171;\u043d\u0435 \u0440\u0443\u043a\u0430\u043c\u0438&#187; \u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c. <strong>Inernal DSL \u0438 \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u0431\u0445\u043e\u0434\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 (\u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435: \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 c \u043f\u0440\u043e\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0443\u0437\u043b\u043e\u0432) <\/strong>. \u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0441\u043a\u0440\u043e\u043c\u043d\u044b\u0439, \u043d\u043e \u043e\u043d \u0432\u0430\u0436\u0435\u043d \u0442\u0435\u043c, \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u0443, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u043e\u043a\u0440\u0443\u0433 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e Internal <strong>DSL Includes<\/strong> (\u0434\u0438\u0430\u043b\u0435\u043a\u0442 \u0442\u043e\u0433\u043e Include\/ThenInclude \u0447\u0442\u043e \u0438\u0437 <a href=\"https:\/\/docs.microsoft.com\/en-us\/ef\/#pivot=efcore\">EF Core<\/a>) \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044e Internal DSL \u0432 \u0446\u0435\u043b\u043e\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. <\/p>\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-287476","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/287476","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=287476"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/287476\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=287476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=287476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=287476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}