рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреЗрдбрд╝ - рдХреНрд░рдордмрджреНрдз, рдХреЙрдкреА, рдХреНрд▓реЛрди, рд╕рдорд╛рди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдЧрддрд┐рд╢реАрд▓ рдирд┐рд░реНрдорд╛рдг (рднрд╛рдЧ I)


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


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


рдкрд░рд┐рдЪрдп


рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ:


var p = new Point(){X=-1,Y=1}; // which has better performance ? var json1 = JsonConvert.SerializeObject(p); var json2 = $"{{\"X\":{pX}, \"Y\":{pY}}}"; 

рджреВрд╕рд░реА рд╡рд┐рдзрд┐ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рддреЗрдЬрд╝ рд╣реИ (рдиреЛрдбреНрд╕ рдЬреНрдЮрд╛рдд рд╣реИрдВ рдФрд░ "рдХреЛрдб рдореЗрдВ crammed" рд╣реИрдВ), рдЬрдмрдХрд┐ рд╡рд┐рдзрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рдЖрдкрдХреЛ рдпрд╣ рдХреЛрдб рдПрдХ рдлрд╝рдВрдХреНрд╢рди (рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдФрд░ рд╕рдВрдХрд▓рд┐рдд) рдХреЗ рд░реВрдк рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рдЬрдЯрд┐рд▓рддрд╛ рдЫрд┐рдкреА рд╣реЛрддреА рд╣реИ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬреЛ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИ рд╡рд╣ рдЫрд┐рдкреА рд╣реЛрддреА рд╣реИ)
рдХрд╣рд╛рдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рд╣реИ рдФрд░ рдХреЛрдб рдкреАрдврд╝реА рд░рдирдЯрд╛рдЗрдо рдХрд╣рд╛рдВ рд╣реИ)ред


 var p = new Point(){X=-1,Y=1}; // which has better performance ? var json1 = JsonConvert.SerializeObject(p); var formatter = JsonManager.ComposeFormatter<Point>(); var json2 = formatter(p); 

рдпрд╣рд╛рдБ JsonManager.ComposeFormatter рдЕрд╕рд▓реА рдЯреВрд▓ рд╣реИ ред рд╡рд╣ рдирд┐рдпрдо рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рджреМрд░рд╛рди рд╕рдВрд░рдЪрдирд╛ рдмрд╛рдИрдкрд╛рд╕ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ, рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ "рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде, рдХрд╕реНрдЯрдо рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реНрддрд░ рдХреЗ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдЬрд╛рддреЗ рд╣реИрдВ"ред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ:


 //    var formatter2 = JsonManager.ComposeFormatter<Point>( chain=>chain .Include(e=>eX) .Include(e=>eY) // DSL Includes ) 

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


рд╡рд╣ рдХреИрд╕реЗ рдХрд░рддрд╛ рд╣реИ - рдХреЛрдб рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреЗрдбрд╝ рдХреЛрдб рдкреАрдврд╝реА рдЧрд╛рдЗрдб рдХрд╛ рдПрдХ рдмрд╣реБрдд ...

serilizer рд╕реЗ serilizer (рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреЗрдбрд╝ рдХреЗ рдмрд┐рдирд╛ рдЕрдм рддрдХ) рдореЗрдВ рд╕рдВрдХреНрд░рдордг:


  Func<StringBuilder, Point, bool> serializer = ... // later string formatter(Point p) { var stringBuilder = new StringBuilder(); serializer(stringBuilder, p); return stringBuilder.ToString(); } 

рдмрджрд▓реЗ рдореЗрдВ, serializer рдЗрд╕ рддрд░рд╣ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдпрджрд┐ рд╕реНрдерд┐рд░ рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ):


 Expression<Func<StringBuilder, Point, bool>> serializerExpression = SerializeAssociativeArray(sb, p, (sb1, t1) => SerializeValueProperty(sb1, t1, "X", o => oX, SerializeValueToString), (sb4, t4) => SerializeValueProperty(sb1, t1, "Y", o => oY, SerializeValueToString) ); Func<StringBuilder, Point, bool> serializer = serializerExpression.Compile(); 

рдпрд╣ рдЗрддрдирд╛ "рдХрд╛рд░реНрдпрд╛рддреНрдордХ" рдХреНрдпреЛрдВ рд╣реИ, рдЖрдк рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреЛ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ: рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ Expression<Func<StringBuilder, Box, bool>> рдЖрджрд┐ рдХреЗ рдПрдХ рдЪрд░ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдЕрд░реНрдзрд╡рд┐рд░рд╛рдо рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред
рдореИрдВ рд╕реАрдзреЗ Func<StringBuilder, Point, bool> serializer = (sb,p)=>SerializeAssociativeArray(sb,p,... рдХреНрдпреЛрдВ рдирд╣реАрдВ рд▓рд┐рдЦ рд╕рдХрддрд╛? рдпрд╣ рд╕рдВрднрд╡ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдПрдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╡рд┐рдзрд╛рдирд╕рднрд╛ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реНрдерд┐рд░ рдХреЛрдб) рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкреЗрдбрд╝, рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХрд▓рди рдХреЗ рд╕рд╛рде, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрдкрдпреЛрдЧ рдореЗрдВ, serializerExpression рдПрдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ - рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ (рдиреАрдЪреЗ) рд╕реЗрдЯ serializerExpression рдЬрд╛рдПрдЧрд╛ред


рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рд╣реА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ: SerializeAssociativeArray params Func<..> propertySerializers рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ params Func<..> propertySerializers рдЕрдиреБрд╕рд╛рд░ params Func<..> propertySerializers рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдиреЛрдбреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ред рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рдХреЗ рдкрддреНрддрд┐рдпреЛрдВ рдХреЗ SerializeValueProperty рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХреЛрдВ (SerializeValueToString рдлрд╝реЙрд░реНрдореИрдЯрд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛) рдФрд░ рджреВрд╕рд░реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ SerializeAssociativeArray (рдпрд╛рдиреА, рд╢рд╛рдЦрд╛рдУрдВ) рджреНрд╡рд╛рд░рд╛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рдХрд╛ рдПрдХ рдЗрдЯрд░реЗрдЯрд░ (рдЯреНрд░реА) рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдЕрдЧрд░ рдкреЙрдЗрдВрдЯ рдореЗрдВ рдиреЗрдХреНрд╕реНрдЯрдкреЙрдЗрдВрдЯ рдкреНрд░реЙрдкрд░реНрдЯреА рд╣реИ:


 var @delegate = SerializeAssociativeArray(sb, p, (sb1, t1) => SerializeValueProperty(sb1, t1, "X", o => oX, SerializeValueToString), (sb4, t4) => SerializeValueProperty(sb1, t1, "Y", o => oY, SerializeValueToString), (sb4, t4) => SerializeValueProperty(sb1, t1, "NextPoint", o => o.NextPoint, (sb4, t4) =>SerializeAssociativeArray(sb1, p1, (sb1, t1) => SerializeValueProperty(sb2, t2, "X", o => oX, SerializeValueToString), (sb4, t4) => SerializeValueProperty(sb2, t2, "Y", o => oY, SerializeValueToString) ) ) ); 

рддреАрди рдХрд╛рд░реНрдпреЛрдВ SerializeAssociativeArray , SerializeValueProperty , SerializeValueToString рдХреА рдбрд┐рд╡рд╛рдЗрд╕ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ:


рд╕реАрд░рд┐рдпрд▓ рдХрд░реЗрдВ ...
 public static bool SerializeAssociativeArray<T>(StringBuilder stringBuilder, T t, params Func<StringBuilder, T, bool>[] 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<T, TProp>(StringBuilder stringBuilder, T t, string propertyName, Func<T, TProp> getter, Func<StringBuilder, TProp, bool> 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<T>(StringBuilder stringBuilder, T t) where T : struct { stringBuilder.Append(t); return true; } 

рдХрдИ рд╡рд┐рд╡рд░рдг рдпрд╣рд╛рдВ рдирд╣реАрдВ рджрд┐рдП рдЧрдП рд╣реИрдВ (рд╕реВрдЪреА рд╕рдорд░реНрдерди, рд╕рдВрджрд░реНрдн рдкреНрд░рдХрд╛рд░ рдФрд░ рдЕрд╢рдХреНрдд)ред рдФрд░ рдлрд┐рд░ рднреА рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдЬрд╕рди рдорд┐рд▓рддрд╛ рд╣реИ, рдФрд░ рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдорд╛рдирдХ рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рднреА рдЕрдзрд┐рдХ рд╣реИ SerializeArray , SerializeNullable , SerializeRef ред


рдпрд╣ рдПрдХ рд╕реНрдерд┐рд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЯреНрд░реА рдерд╛, рдЧрддрд┐рд╢реАрд▓ рдирд╣реАрдВ, C # рдореЗрдВ eval рдирд╣реАрдВред


рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЯреНрд░реА рдХреЛ рджреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


рдЪрд░рдг 1 - Expression<T> рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЛрдб рдкрд░ рдбрд┐рдХрдореНрдкрд╛рдЗрд▓рд░ рджреЗрдЦреЛ



рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рдкрд╣рд▓реА рдмрд╛рд░ рдЖрд╢реНрдЪрд░реНрдп рд╣реЛрдЧрд╛ред рдХреБрдЫ рднреА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкрд╣рд▓реА рдЪрд╛рд░ рд▓рд╛рдЗрдиреЗрдВ рдХрд┐рд╕ рддрд░рд╣ рдПрдХ рд╕рд╛рде рд░рдЦреА рдЬрд╛рддреА рд╣реИрдВ:


 ("sb","t") .. SerializeAssociativeArray.. 

рдлрд┐рд░ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдпрджрд┐ рдЖрдк рдЗрд╕ рддрд░рд╣ рдХреЗ рд░рд┐рдХреЙрд░реНрдб ('рдПрдХреНрд╕рдкреНрд░реЗрд╢рди.рдХреЙрдиреНрд╕реНрдЯ', 'рдПрдХреНрд╕рдкреНрд░реЗрд╢рди.рдкреНрд░реЗрдо,', 'рдПрдХреНрд╕рдкреНрд░реЗрд╢рди.рдХреЙрд▓', 'рдПрдХреНрд╕рдкреНрд░реЗрд╢рди.рд▓рдореНрдмрд╛' рдЖрджрд┐ ...) рдореЗрдВ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд░рдЪрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдиреЛрдбреНрд╕ рдХреЗ рдХрд┐рд╕реА рднреА рдмрд╛рдИрдкрд╛рд╕ (рдЖрдзрд╛рд░рд┐рдд) рдореЗрдЯрд╛рдбрд╛рдЯрд╛)ред рдпрд╣ C # рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд╣реИред


рдЪрд░рдг 2 - рдЗрд╕ рд▓рд┐рдВрдХ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░реЗрдВ ,


рдПрдХ рд╣реА рдбрд┐рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛрдб, рд▓реЗрдХрд┐рди рдЖрджрдореА рджреНрд╡рд╛рд░рд╛ рд╕рдВрдХрд▓рд┐рддред


рдЗрд╕ рдордирдХреЗ рдХрдврд╝рд╛рдИ рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рд▓реЗрдЦрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпреЗ рд╕рднреА рдХрд▓рд╛рдПрдБ рдХреНрд░рдордмрджреНрдзрддрд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЕрдВрджрд░ рд░рд╣рддреА рд╣реИрдВред рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рд╕реАрдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЖрдк рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХреБрд╢рд▓ рдХрд╛рд░реНрдп C # ((.NET .NET)) рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдХрд░рд╛ рд╕рдХрддреЗ рд╣реИрдВред


рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рдЖрдк рд╣рд░ рдмрд╛рд░ рд╕рдВрдХрд▓рди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рдВрдХрд▓рди рдХрд╣рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдЖрдЧреЗ рдирд┐рдХрд▓ рдЬрд╛рдПрдЧрд╛ ( ComposeFormatter рдЕрдВрджрд░ рд╕рдВрдХрд▓рди рдПрдХ рдорд╣рдВрдЧрд╛ рдСрдкрд░реЗрд╢рди рд╣реИ), рд▓реЗрдХрд┐рди рдЖрдк рд▓рд┐рдВрдХ рдХреЛ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 static Func<Point, string> formatter = JsonManager.ComposeFormatter<Point>(); public string Get(Point p){ // which has better performance ? var json1 = JsonConvert.SerializeObject(p); var json2 = formatter(p); return json2; } 

рдпрджрд┐ рдЖрдкрдХреЛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЧреБрдордирд╛рдо рдкреНрд░рдХрд╛рд░ рдХреЗ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдмрдирд╛рдиреЗ рдФрд░ рдмрдЪрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 static CachedFormatter cachedFormatter = new CachedFormatter(); public string Get(List<Point> 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=> {X:eX, Sum:e.X+EY}) .ToJson(cachedFormatter, e=>e.Sum); return json3; } 

рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдЖрддреНрдорд╡рд┐рд╢реНрд╡рд╛рд╕ рд╕реЗ рдЕрдкрдиреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рдорд╛рдЗрдХреНрд░реЛрдПрдкреНрдЯрд┐рдорд╛рдЗрдЬреЗрд╢рди рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ рдФрд░ рдЬрдорд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдорд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдорд╛ рдХрд░рддреЗ рд╣реИрдВ ... рдХреМрди рдордЬрд╛рдХ рд╣реИ, рдХреМрди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рд╕рд╡рд╛рд▓ рдкрд░ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдирдпрд╛ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдирдпрд╛ рд╣реИ, рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд▓рд╛рдн рдХреЛ рдареАрдХ рдХрд░рддрд╛ рд╣реВрдВ - рдпрд╣ рддреЗрдЬреА рд╕реЗ рд╣реЛрдЧрд╛ред


рдмрджрд▓реЗ рдореЗрдВ рдХреНрдпрд╛?


рдбреАрдПрд╕рдПрд▓ рдореЗрдВ рд╕реАрд░рд▓рд╛рдЗрдЬрд╝ рдореЗрдВ рджреБрднрд╛рд╖рд┐рдпрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ (рдФрд░ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рдпрд╣ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдореЗрдВ рд╕рдВрднрд╡ рд╣реИ, рдкреНрд░рддрд┐рд▓рд┐рдкрд┐, рдХреНрд▓реЛрди - рдФрд░ рдпрд╣ рднреА рд╣реЛрдЧрд╛) рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд╛рдЧрддреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


1 - рд╕рдВрдХрд▓рд┐рдд рдХреЛрдб рдХреЗ рд▓рд┐рдВрдХ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХреА рд▓рд╛рдЧрддред


рдпреЗ рд▓рд╛рдЧрдд рдЖрдо рддреМрд░ рдкрд░ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╕рдВрдХрд▓рди рдХреЗ рд╕рд╛рде рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреЗрдбрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЛрддрд╛ рд╣реИ - рджреБрднрд╛рд╖рд┐рдпрд╛ рд░рд┐рдлреНрд▓реЗрдХреНрд╕реЗрд╕ рдкрд░ рдПрдХ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЗрд╕реЗ рдЗрддрдирд╛ рдЪрд╛рдЯ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдзрд╛рд░рд╛ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХреЛрдВ (рдЬреИрд╕реЗ, рдХреЙрдкреА, рдХреНрд▓реЛрди) рдФрд░ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкреЗрдбрд╝реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд░рд╛рдмрд░реА рдПрдХрддреНрд░ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рди рд╣реА рдЙрдиреНрд╣реЗрдВ рдкрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕рд░реНрд╡рд┐рд╕рд╕реНрдЯреИрдХ рдФрд░ Json.NET рдХреЛ рдУрд╡рд░рдЯреЗрдХ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЗрд╕ рддрд░рд╣ рдХрд╛ рдХреЛрдИ рдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ, рдЬреЛрд╕рди рдореЗрдВ рдХреНрд░рдордмрджреНрдзрддрд╛ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕реБрд╡рд┐рдЪрд╛рд░рд┐рдд рдХрд╛рд░реНрдп рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рд╣реИ - рдПрдХ рдирдпрд╛ рд╕рдорд╛рдзрд╛рди рдкреЗрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд╢реНрдпрдХ рд╢рд░реНрдд)ред


2 - рдЖрдкрдХреЛ рдЕрдореВрд░реНрдд рдХреЗ рд▓реАрдХ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдПрдХ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдореМрдЬреВрджрд╛ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╢рдмреНрджрд╛рд░реНрде рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрдиред


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреЙрдЗрдВрдЯ рдФрд░ IEnumerable рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

 var formatter1 = JsonManager.ComposeFormatter<Point>(); var formatter2 = JsonManager.ComposeEnumerableFormatter<Point>(); // but not // var formatter2 = JsonManager.ComposeEnumerableFormatter<List<Point>>(); 

рдпрд╛: "рдХреНрд▓реЛрдЬрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?"ред рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдиреЛрдб рдХреЛ рдирд╛рдо рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЕрджреНрд╡рд┐рддреАрдп):


 string DATEFORMAT= "YYYY"; var formatter3 = JsonManager.ComposeFormatter<Record>( chain => chain .Include(i => i.RecordId) .Include(i => i.CreatedAt.ToString(DATEFORMAT) , "CreatedAt"); ); 

рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ ComposeFormatter рд╕реЗ ComposeFormatter рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рдЖрдВрддрд░рд┐рдХ рдЙрдкрдХрд░рдг рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд▓рд╛рдЧрдд рдЕрдкрд░рд┐рд╣рд╛рд░реНрдп рдмреБрд░рд╛рдИ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдкрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдФрд░ рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдХреЗ рджрд╛рдпрд░реЗ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рд╕реЗ, рдЕрдореВрд░реНрдд рдХрд╛ рд░рд┐рд╕рд╛рд╡ рднреА рдмрдврд╝рддрд╛ рд╣реИред рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдХреЗ рдбреЗрд╡рд▓рдкрд░ рдкрд░ рдЕрддреНрдпрд╛рдЪрд╛рд░ рдХрд░реЗрдЧрд╛, рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рджрд╛рд░реНрд╢рдирд┐рдХ рдордиреЛрджрд╢рд╛ рдкрд░ рд╕реНрдЯреЙрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдП, рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ ( рдХреНрдпрд╛ рдЙрдореНрдореАрдж рдХрд░реЗрдВ? ) рдХреЗ рддрдХрдиреАрдХреА рд╡рд┐рд╡рд░рдг рдФрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбреАрдПрд╕рдПрд▓ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рд╕рдореГрджреНрдзрд┐ рдФрд░ рдЗрд╕рдХреЗ рджреБрднрд╛рд╖рд┐рдпреЛрдВ ( рдмрджрд▓реЗ рдореЗрдВ рдХреНрдпрд╛? ) рдХреЗ рдЬреНрдЮрд╛рди рд╕реЗ рдЕрдореВрд░реНрдд рд▓реАрдХ рдХреЛ рджреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░: "рдХреНрдпрд╛ рдпрд╣ рдЖрдВрддрд░рд┐рдХ рдбреАрдПрд╕рдПрд▓ рдмрдирд╛рдиреЗ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ?", рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдбреАрдПрд╕рдПрд▓ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдХрд╣рд╛рдиреА рд╣реЛ рд╕рдХрддреА рд╣реИ - рдЗрд╕рдХреЗ рд╕рднреА рд╡рд┐рд╡рд░рдг рдФрд░ рдЙрдкрдпреБрдХреНрддрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдФрд░ рдЗрд╕рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ (рджреБрднрд╛рд╖рд┐рдпреЛрдВ), рдЕрд░реНрдерд╛рддреНред рд▓рд╛рдЧрдд рдкрд░ рдХрд╛рдмреВ рдкрд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдХрд╣рд╛рдиреАред


рдЗрд╕ рд╕рдм рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдореИрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбреАрдПрд╕рдПрд▓ рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖрддрд╛ рд╣реВрдВред


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


рд╕рд░рд▓реАрдХрд░рдг рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:


  1. рдмрд╛рдИрдкрд╛рд╕ рдЯреНрд░реА (рдиреЛрдбреНрд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреНрд░рдорд╛рдВрдХрди рд╣реЛрдЧрд╛, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ рдкрд░рд┐рдкрддреНрд░ рд▓рд┐рдВрдХ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ), рдкрддреНрддрд┐рдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ - рдПрдХ рдлреЙрд░реНрдореЗрдЯрд░ (рдкреНрд░рдХрд╛рд░ рд╕реЗ) рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВред
  2. рдкрддреНрддрд┐рдпреЛрдВ рд╕рд╣рд┐рдд рдирд┐рдпрдо (рдпрджрд┐ рд╡реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИрдВ) - рд╕рдВрдкрддреНрддрд┐ рдмрдирд╛рдо рдлрд╝реАрд▓реНрдб? рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП?
  3. рдПрдХ рд╢рд╛рдЦрд╛ (рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЗ рд╕рд╛рде рдПрдХ рдиреЛрдб) рдФрд░ рдПрдХ рд╢реАрдЯ рджреЛрдиреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ e=>e.Name ( e=>e.Name ) рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдо рддреМрд░ рдкрд░ рдХреЛрдИ рднреА рдлрд╝рдВрдХреНрд╢рди (`e => e.Name.ToUpper) ()," MymemberName ") - рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЗ рд▓рд┐рдП рдлрд╝реЙрд░реНрдореЗрдЯрд░ рд╕реЗрдЯ рдХрд░реЗрдВ рдиреЛрдбред

рд▓рдЪреАрд▓рд╛рдкрди рдмрдврд╝рд╛рдиреЗ рдХреЗ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк:


  1. рдПрдХ рд╢реАрдЯ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдЬрд╕рди рд╣реЛрддрд╛ рд╣реИ "рдЬреИрд╕рд╛ рдХрд┐" рд╕реНрдЯреНрд░рд┐рдВрдЧ (рд╡рд┐рд╢реЗрд╖ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдлреЙрд░реНрдореЗрдЯрд░) рд╣реИ;
  2. рд╕рдореВрд╣реЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд░реВрдкрдХ рд╕реЗрдЯ рдХрд░реЗрдВ, рдЕрд░реНрдерд╛рдд рдкреВрд░реА рд╢рд╛рдЦрд╛рдПрдБ, рдЗрд╕ рд╢рд╛рдЦрд╛ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рд╕реЗ - рдПрдХ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдордп рдХреЗ рд╕рд╛рде рдпрд╣рд╛рдБ рддрд╛рд░реАрдЦреЗрдВ, рдФрд░ рдЗрд╕ рд╕рдордп рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдореЗрдВ)ред

рд╣рд░ рдЬрдЧрд╣ рдРрд╕реЗ рдирд┐рд░реНрдорд╛рдг рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: рдмрд╛рдпрдкрд╛рд╕ рдЯреНрд░реА, рд╢рд╛рдЦрд╛, рдкрддреНрддреА, рдФрд░ рдпрд╣ рд╕рдм DSL рд╢рд╛рдорд┐рд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдбреАрдПрд╕рдПрд▓ рд╢рд╛рдорд┐рд▓ рд╣реИ


рдЪреВрдВрдХрд┐ рд╣рд░ рдХреЛрдИ рдИрдПрдл рдХреЛрд░ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдирд┐рдореНрди рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рдЕрд░реНрде рдХреЛ рддреБрд░рдВрдд рдкрдХрдбрд╝ рд▓рд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрд╣ xpath рдХрд╛ рд╕рдмрд╕реЗрдЯ рд╣реИ)ред


  // DSL Includes Include<User> include1 = chain=> chain .IncludeAll(e => e.Groups) .IncludeAll(e => e.Roles) .ThenIncludeAll(e => e.Privileges) // EF Core syntax // https://docs.microsoft.com/en-us/ef/core/querying/related-data var users = context.Users .Include(blog => blog.Groups) .Include(blog => blog.Roles) .ThenInclude(blog => blog.Privileges); 

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


 Include<User> include2 = chain=> chain .Include(e => e.UserName) // leaf member .IncludeAll(e => e.Groups) .ThenInclude(e => e.GroupName) // leaf member .IncludeAll(e => e.Roles) .ThenInclude(e => e.RoleName) // leaf member .IncludeAll(e => e.Roles) .ThenIncludeAll(e => e.Privileges) .ThenInclude(e => e.PrivilegeName) // leaf member 

рдпрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдирд┐рдпрдо рд╕реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдЬреЛрдбрд╝реЗрдВ:


 // Func<ChainNode, MemberInfo> rule = ... var include2 = IncludeExtensions.AppendLeafs(include1, rule); 

рдпрд╣рд╛рдБ рдирд┐рдпрдо рдПрдХ рдирд┐рдпрдо рд╣реИ рдЬрд┐рд╕реЗ ChainNode.Type рджреНрд╡рд╛рд░рд╛ рдЪреБрдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдиреЛрдб рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдИ рдЧрдИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкреНрд░рдХрд╛рд░ (рдЪреЗрдирдиреЛрдб - рдбреАрдПрд╕рдПрд▓ рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдмрд╛рдж рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреА) рдХреНрд░рдорд╛рдВрдХрди рдореЗрдВ рднрд╛рдЧреАрджрд╛рд░реА рдХреЗ рд▓рд┐рдП рдЧреБрдг (рдореЗрдВрдмрд░рдлреЛ), рдЬреИрд╕реЗред рдХреЗрд╡рд▓ рд╕рдВрдкрддреНрддрд┐, рдпрд╛ рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ / рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдкрддреНрддрд┐, рдпрд╛ рдХреЗрд╡рд▓ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝реЙрд░реНрдореЗрдЯрд░ рд╣реИ, рдЖрдк рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╕реЗ рдЪрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЛ рднреА рд╕реНрд╡рдпрдВ рдПрдХ рдирд┐рдпрдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдпрджрд┐ рдпрд╣ рдкрддреНрддреА рдХреЗ рдиреЛрдбреНрд╕ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рддрд╛ рд╣реИ - рдЕрд░реНрдерд╛рдд, рдкреЗрдбрд╝ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдХрд╛ рд░реВрдк) ред


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


рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░


рдИрдПрдл рдХреЛрд░ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдгред
рд░рдирд┐рдВрдЧ рдХрд╛рд░реНрдп "рдЪрдХреНрд░реАрдп рд▓рд┐рдВрдХ рдХреЛ рдХрд╛рдЯ рджреЗрдирд╛" рд╣реИ, рдХреЗрд╡рд▓ рд╡рд╣реА рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рдХрд┐ рд╢рд╛рдорд┐рд▓-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИ:


 static CachedFormatter cachedFormatter1 = new CachedFormatter(); string GetJson() { using (var dbContext = GetEfCoreContext()) { string json = EfCoreExtensions.ToJsonEf<User>(cachedFormatter1, dbContext, chain=>chain .IncludeAll(e => e.Roles) .ThenIncludeAll(e => e.Privileges)); } } 

ToJsonEf рдиреЗрд╡рд┐рдЧреЗрд╢рди рдЕрдиреБрдХреНрд░рдо рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЬрдм рдХреНрд░рдордмрджреНрдз рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ("EF рдХреЛрд░ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ" рдирд┐рдпрдо рд╕реЗ рдкрддреНрддрд┐рдпреЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдкрдарди / рд▓реЗрдЦрди рд╕рдВрдкрддреНрддрд┐), рдореЙрдбрд▓ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддрд╛ рд╣реИ - рдЬрд╣рд╛рдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ / json рдлрд╝реАрд▓реНрдб рд╕реНрд╡рд░реВрдкрдг рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ (рдмрд╛рдЗрдЯ [] рдкреНрд░рддрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдЖрдИрдПрд╕рдУ рдореЗрдВ рдбреЗрдЯрд╛рдЗрдо, рдЖрджрд┐)ред рдЗрд╕рд▓рд┐рдП, рдЙрд╕реЗ рдЕрдкрдиреЗ рдЕрдзреАрди рд╕реЗ рд╣реА IQugeable рдкреНрд░рджрд░реНрд╢рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдм рдкрд░рд┐рдгрд╛рдо рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдирд┐рдпрдо рдмрджрд▓ рдЬрд╛рддреЗ рд╣реИрдВ - DSL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдЗрд╕рдореЗрдВ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ (рдпрджрд┐ рдирд┐рдпрдо рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ), рдПрдХ рдФрд░ рджреБрднрд╛рд╖рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рд╣реЛрддрд╛ рд╣реИ:


 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 => e.Roles) .ThenIncludeAll(e => e.Privileges) .Select(e => new { FieldA: e.FieldA, FieldJson:"[1,2,3]", Role: e.Roles().First() }) .ToJson(cachedFormatter1, chain => chain.Include(e => e.Role), LeafRuleManager.DefaultEfCore, config: rules => rules .AddRule<string[]>(GetStringArrayFormatter) .SubTree( chain => chain.Include(e => e.FieldJson), stringAsJsonLiteral: true) // json as is .SubTree( chain => chain.Include(e => e.Role), subRules => subRules .AddRule<DateTime>( dateTimeFormat: "YYYMMDD", floatingPointFormat: "N2" ) ), ), useToString: false, // no default ToString for unknown leaf type (throw exception) dateTimeFormat: "YYMMDD", floatingPointFormat: "N2" } } 

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


рдпрд╣ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ : рд╣рд╛рд▓рд╛рдВрдХрд┐ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЬреНрдЮрд╛рди рд╣рдореЗрд╢рд╛ рдПрдПрд╕рдкреА рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рд╡реЗрдм рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдмрд╣реБрдд рд╣реА рдЖрд╡рд╢реНрдпрдХ рдЪреАрдЬ рдирд╣реАрдВ рд╣реИ, рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛рдмреЗрд╕ рднреА рдбреЗрдЯрд╛ рдХреЛ рдЬрд╕рди рдореЗрдВ рд╕рдВрдЪрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдПрд╕рдкреА рдПрдорд╡реАрд╕реА рдореЗрдВ рдбреАрдПрд╕рдПрд▓ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдХрд╣рд╛рдиреА рдирд╣реАрдВ рд╣реИ ред рдПрдПрд╕рдкреА рдПрдорд╡реАрд╕реА рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреЛ рдХреИрд╕реЗ рдорд┐рд▓рд╛рдПрдВ рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдЕрдзреНрдпрдпрди рдХреЗ рдпреЛрдЧреНрдп рд╣реИред


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


рдЕрдзрд┐рдХ рдбреАрдПрд╕рдПрд▓ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ


 Include<Point> include = chain => chain.Include(e=>eX).Include(e=>eY); 

рдпрд╣ EF рдХреЛрд░ рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реНрдерд┐рд░ рдХрд╛рд░реНрдп рд╢рд╛рдорд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЪрд░ рдХреЛ рдирд╣реАрдВ рд╕реМрдВрдкрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдбреАрдПрд╕рдПрд▓ рдореЗрдВ рдЦреБрдж рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рдореЗрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ "рд╢рд╛рдорд┐рд▓" рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдмрд╛рд╣рд░ рдкреИрджрд╛ рд╣реБрдЖ рдерд╛, рдмрд┐рдирд╛ рдЯрд╛рдЗрдк рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рдХреЗ рдмрд┐рдирд╛, рдЬрдм рд╡реЗ рддрд╛рд░ рдореЗрдВ рдорд╛рдирдХреАрдХреГрдд рд╣реЛрддреЗ рдереЗред


рдирд┐рдпреБрдХреНрддрд┐ рдореЗрдВ рд╕рдмрд╕реЗ рдирд╛рдЯрдХреАрдп рдЕрдВрддрд░ рдЕрднреА рднреА рд╣реИред рдИрдПрдл рдХреЛрд░ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ - рдиреЗрд╡рд┐рдЧреЗрд╢рди (рд╢рд╛рдЦрд╛рдУрдВ рдХреА рдиреЛрдбреНрд╕) рдХреЗ рдЧреБрдгреЛрдВ рдХрд╛ рд╕рдорд╛рд╡реЗрд╢, рдбреАрдПрд╕рдПрд▓ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ - рдкреНрд░рддреНрдпреЗрдХ рдЧрдгрдирд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдПрдХ рдирд╛рдо (рдкрде) рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реБрдП рдЧрдгрдирд╛ рдХреЗ рдПрдХ рдкреЗрдбрд╝ рдХреЗ рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рдХрд╛ рд░рд┐рдХреЙрд░реНрдбред


EF Core рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдореЗрдВ e=>User.Name Expression.Member рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдкреНрдд рддрд╛рд░ рдХреА рдПрдХ рд╕реВрдЪреА рд╢рд╛рдорд┐рд▓ рд╣реИ ( e=>User.Name рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐)ред e=>User.Name рдХреЗрд╡рд▓ [ e=>User.Name ] рд╣реЛ рд╕рдХрддрд╛ рд╣реИ ( https://msdn.microsoft.com/en-us/usibrary/system.linq.expressions)ред рдореЗрдореНрдмреНрд░реЗрдХреНрд╕рдкреНрд░реЗрд╢рди (v = рдмрдирд╛рдо 110) .aspx рдФрд░ рдЖрдВрддрд░рд┐рдХ рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рдХреЗрд╡рд▓ Name рд░реЗрдЦрд╛ рдмрдЪ рдЬрд╛рддреА рд╣реИ)ред


DSL рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ ChainNode рдФрд░ ChainMemberNode рдХрдХреНрд╖рд╛рдПрдВ рд╣реИрдВ рдЬреЛ рд╕рдВрдкреВрд░реНрдг рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ (рдЬреИрд╕реЗ e=>User.Name ) рдХреЛ e=>User.Name , рдЬреЛ рдХрд┐, рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╣реИ, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдкреЗрдбрд╝ рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рдмрд╛рдд рд╕реЗ рдареАрдХ рд╣реИ рдХрд┐ DSL рдореЗрдВ рдлрд╝реАрд▓реНрдб рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдорд╛рди рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:


рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди:


 Include<User> include = chain => chain .Include(i => i.UserName) .Include(i => i.Email.ToUpper(),"EAddress"); 

рдЗрд╕рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ рдпрд╣ рджреБрднрд╛рд╖рд┐рдпрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред CreateFormatter- {"UserName": "John", "ERddress": "JOHN@MAIL.COM"} рд╡рд╛рдкрд╕ рдЖрдПрдЧрд╛


рдирд┐рд╖реНрдкрд╛рджрди рдЕрд╢рдХреНрдд рд╕рдВрд░рдЪрдирд╛рдУрдВ рдкрд░ рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


 Include<StrangePointF> include = chain => chain .Include(e => e.NextPoint) // NextPoint is nullable struct .ThenIncluding(e => e.Value.X) .ThenInclude(e => e.Value.Y); // but not this way (abstraction leak) // Include<StrangePointF> include // = chain => chain // now this can throw an exception // .Include(e => e.NextPoint.Value) // .ThenIncluding(e => eX) // .ThenInclude(e => eY); 

рдбреАрдПрд╕рдПрд▓ рдореЗрдВ рдорд▓реНрдЯреА-рд▓реЗрд╡рд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИред


 Include<User> include = chain => chain .Include(i => i.UserName) .IncludeAll(i => i.Groups) // ING-form - doesn't change current node .ThenIncluding(e => e.GroupName) // leaf .ThenIncluding(e => e.GroupDescription) // leaf .ThenInclude(e => e.AdGroup); // leaf 

рд╕реЗ рддреБрд▓рдирд╛ рдХрд░реЗрдВ


 Include<User> include = chain => chain .Include(i => i.UserName) .IncludeAll(i => i.Groups) .ThenInclude(e => e.GroupName) .IncludeAll(i => i.Groups) .ThenInclude(e => e.GroupDescription) .IncludeAll(i => i.Groups) .ThenInclude(e => e.AdGroup); 

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


рдмреАрдЬрдЧрдгрд┐рдд рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ ред


рд╢рд╛рдорд┐рд▓ рднрд╛рд╡ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:


Cravnivat
 var b1 = InlcudeExtensions.IsEqualTo(include1, include2); var b2 = InlcudeExtensions.IsSubTreeOf(include1, include2); var b3 = InlcudeExtensions.IsSuperTreeOf(include1, include2); 

рдХреНрд▓реЛрди
 var include2 = InlcudeExtensions.Clone(include1); 

рдХрдореНрдмрд╛рдЗрди (рдорд░реНрдЬ)
 var include3 = InlcudeExtensions.Merge(include1, include2); 

XPath рд╕реВрдЪрд┐рдпреЛрдВ рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░реЗрдВ - рдкрддреНрдерд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкрде
 IReadOnlyCollection<string> paths1 = InlcudeExtensions.ListLeafXPaths(include); // as xpaths IReadOnlyCollection<string[]> paths2 = InlcudeExtensions.ListLeafKeyPaths(include); // as string[] 

рдЖрджрд┐


рдЕрдЪреНрдЫреА рдЦрдмрд░ рдпрд╣ рд╣реИ: рдЕрдореВрд░реНрддрддрд╛ рдХреА рдХреЛрдИ рд▓реАрдХ рдирд╣реАрдВ рд╣реИ, рд╢реБрджреНрдз рдЕрдореВрд░реНрдд рдХрд╛ рд╕реНрддрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдкрд╣реБрдВрдЪ рдЧрдпрд╛ рд╣реИред рдореЗрдЯрд╛рдбреЗрдЯрд╛ рд╣реИ рдФрд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред


рджреНрд╡рдВрджреНрд╡рд╡рд╛рдж


DSL рдореЗрдВ рдЖрдкрдХреЛ рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рдПрдХ рдирдП рд╕реНрддрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдкрд▓рдмреНрдзрд┐ рдХреЗ рд╕рдордп, рдЕрдЧрд▓реЗ рд╕реНрддрд░ рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд╛ рдЧрдарди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рд╕реНрд╡рдпрдВ рднрд╛рд╡ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВред


рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдзрд╛рд░рд╛рдкреНрд░рд╡рд╛рд╣ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдбреАрдПрд╕рдПрд▓ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рдЖрдкрдХреЛ рдмрд╕ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


 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 eg: var child = root.AddChild("X"); Include<Point> include = ChainNodeExtensions.ComposeInclude<Point>(root); 

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


рдХреЙрдкреА, рдХреНрд▓реЛрди, рдмрд░рд╛рдмрд░


рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рджреБрднрд╛рд╖рд┐рдпреЛрдВ рдХрд╛ рд╕рдЪ рд╣реИ рдЬреЛ рдХреЙрдкреА , рдХреНрд▓реЛрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рдмрд░рд╛рдмрд░ рдХрд░рддреЗ рд╣реИрдВред


рдмрд░рд╛рдмрд░

рд╕рдореНрдорд┐рд▓рд┐рдд-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╕реЗ рдкрддреНрддрд┐рдпреЛрдВ рдкрд░ рдХреЗрд╡рд▓ рддреБрд▓рдирд╛ рдХрд░реЗрдВред
рдЫрд┐рдкреА рд╣реБрдИ рд╢рдмреНрджрд╛рд░реНрде рд╕рдорд╕реНрдпрд╛: рд╕реВрдЪреА рдореЗрдВ рдореВрд▓реНрдпрд╛рдВрдХрди рдпрд╛ рдЖрджреЗрд╢ рдирд╣реАрдВ


 Include<User> include = chain=>chain.Include(e=>e.UserId).IncludeAll(e=>e.Groups).ThenInclude(e=>e.GroupId) bool b1 = ObjectExtensions.Equals(user1, user2, include); bool b2 = ObjectExtensions.EqualsAll(userList1, userList2, include); 

рдХреНрд▓реЛрди

рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдиреЛрдбреНрд╕ рд╕реЗ рдЧреБрдЬрд░реЗрдВред рдирд┐рдпрдо рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЧреБрдгреЛрдВ рдХреА рдирдХрд▓ рдХреА рдЬрд╛рддреА рд╣реИред


 Include<User> include = chain=>chain.Include(e=>e.UserId).IncludeAll(e=>e.Groups).ThenInclude(e=>e.GroupId) var newUser = ObjectExtensions.Clone(user1, include, leafRule1); var newUserList = ObjectExtensions.CloneAll(userList1, leafRule1); 

рдПрдХ рджреБрднрд╛рд╖рд┐рдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдкрддреНрддреА рдХрд╛ рдЪрдпрди рдХрд░реЗрдЧрд╛ред рдРрд╕рд╛ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдПрдХ рдЕрд▓рдЧ рдирд┐рдпрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ? ObjectExtensions.Copy рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдХреЗ рд╕рдорд╛рди рдХреНрдпрд╛ рдерд╛


рдкреНрд░рддрд┐рд▓рд┐рдкрд┐

рдиреЛрдбреНрд╕ рд╕реЗ рдЧреБрдЬрд░реЗрдВ - рдПрдХ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╢рд╛рдЦрд╛ рдФрд░ рдкрддреНрддреА рдиреЛрдбреНрд╕ рджреНрд╡рд╛рд░рд╛ рдкрд╣рдЪрд╛рдиред рдирд┐рдпрдо рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЧреБрдгреЛрдВ рдХреА рдирдХрд▓ рдХреА рдЬрд╛рддреА рд╣реИ (рдХреНрд▓реЛрди рдХреЗ рд╕рдорд╛рди)ред


 Include<User> include = chain=>chain.IncludeAll(e=>e.Groups); ObjectExtensions.Copy(user1, user2, include, supportedLeafsRule); ObjectExtensions.CopyAll(userList1, userList2, include, supportedLeafsRule); 

рдПрдХ рджреБрднрд╛рд╖рд┐рдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдкрддреНрддреА рдХрд╛ рдЪрдпрди рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдПрдХ рдЕрд▓рдЧ рдирд┐рдпрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ? ObjectExtensions.Copy ( тАФ include , supportedLeafsRule тАФ ).


copy / clone :


  1. readonly , Tuple<,> Anonymous Type. , .
  2. (. IEnumerable ) тАФ public .
  3. expression include-, тАФ .
  4. " " .

DSL , .. . , Tuple<,> , .. c readonly , ValueTuple<,> c writabale ( ).


, ( Expression Trees) Includes тАФ . Include DSL .


Detach, FindDifferences ..


run-time, .cs ?


.cs , , run-time :


  1. ( , , source control).
  2. , , , тАФ .
  3. .
  4. " ". dev time , : "" "" , "" , , "" .

Roslyn', . Typescript ( DTO , .. ) тАФ DSL Includes Roslyn' ( ) тАФ typescript ( ). " " " " .cs ( Expression Trees).


: run time тАФ , . ( Expression Trees).


Expression Trees


Internal DSL Expression Tree :


  1. LambdaExpression.Compile Lambda . , . , "" expression tree, CallExpression тАФ LambdaExpression, (. LambdaExpression) ConstantExpression. , " /" тАФ , Expression Trees.


  2. ssmbly , ( 10 ) ( assembly , тАФ ). , , , тАФ .



, ( ), , . : . тАФ тАФ .cs .



тАФ 600 15 . JSON.NET, ServiceStack reflection' GetProperties().


dslComposeFormatter тАФ ComposeFormatter , .


BenchmarkDotNet =v0.10.14, OS=Windows 10.0.17134
Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), 1 CPU, 4 logical and 4 physical cores
.NET Core SDK=2.1.300


MethodMeanErrorStdDevMinMaxMedianAllocated
dslComposeFormatter2.208 ms0.0093 ms0.0078 ms2.193 ms2.220 ms2.211 ms849.47 KB
JsonNet_Default2.902 ms0.0160 ms0.0150 ms2.883 ms2.934 ms2.899 ms658.63 KB
JsonNet_NullIgnore2.944 ms0.0089 ms0.0079 ms2.932 ms2.960 ms2.942 ms564.97 KB
JsonNet_DateFormatFF3.480 ms0.0121 ms0.0113 ms3.458 ms3.497 ms3.479 ms757.41 KB
JsonNet_DateFormatSS3.880 ms0.0139 ms0.0130 ms3.854 ms3.899 ms3.877 ms785.53 KB
ServiceStack_SerializeToString4.225 ms0.0120 ms0.0106 ms4.201 ms4.243 ms4.226 ms805.13 KB
fake_expressionManuallyConstruted54.396 ms0.1758 ms0.1644 ms54.104 ms54.629 ms54.383 ms7401.58 KB

fake_expressionManuallyConstruted тАФ expression ( ).



DSL : DSL ; Internal DSL run-time .


Expression Tree .NET Standard .


Expression Trees Internal DSL Fluent API. # .


fluent ( Expression Trees), Internal DSL # fluent, "" Expression Trees.


Expression Trees DSL Includes ( , ), / run-time тАФ (run-time ).


Internal DSL : - serialize , copy , clone , equals "" . , " ", . : includes ( ) , ( , ).


рдирд┐рд╖реНрдХрд░реНрд╖


DSL Includes DTO тАФ ( json). , , , " ", . = .


Internal DSL , DSL, Internal DSL ( Expression) ( Expression Tree).


DSL Includes json ComposeFormatter DashboardCodes.Routines nuget GitHub.

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


All Articles