рдореЗрд░реА рднрд╛рдЧреАрджрд╛рд░реА рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд░реНрд╖ рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд "рд╕рдВрд╡рд╛рдж" рд╣реБрдЖ:
.Net рдРрдк : рдЕрд░реЗ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ, рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдвреЗрд░ рд╕рд╛рд░рд╛ рдбреЗрдЯрд╛ рджреЗрдВ!
рдЗрдХрд╛рдИ рдврд╛рдБрдЪрд╛ : рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдирд╣реАрдВ рд╕рдордЭрд╛ред рдХреНрдпрд╛ рдорддрд▓рдм?
.Net рдРрдк : рд╣рд╛рдВ, рдореБрдЭреЗ рд╕рд┐рд░реНрдл 100k рд▓реЗрдирджреЗрди рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдорд┐рд▓рд╛ рд╣реИред рдФрд░ рдЕрдм рд╣рдореЗрдВ рд╡рд╣рд╛рдВ рдЗрдВрдЧрд┐рдд рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдкреНрд░рддрд┐рднреВрддрд┐рдпреЛрдВ рдХреА рдХреАрдорддреЛрдВ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреА рдЬрд▓реНрджреА рд╕реЗ рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЗрдХрд╛рдИ рдврд╛рдВрдЪрд╛ : рдЖрд╣, рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ ...
.Net рдРрдк : рдпрд╣рд╛рдБ рдХреЛрдб рд╣реИ:
var query = from p in context.Prices join t in transactions on new { p.Ticker, p.TradedOn, p.PriceSourceId } equals new { t.Ticker, t.TradedOn, t.PriceSourceId } select p; query.ToList();
рдЗрдХрд╛рдИ рдврд╛рдВрдЪрд╛ :

рдХреНрд▓рд╛рд╕рд┐рдХ! рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ: рдЬрдм рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ "рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ" рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рд╕реНрдерд╛рдиреАрдп рд╕рдВрдЧреНрд░рд╣ рдФрд░ рдбреАрдмреАрд╕реЗрдЯ рдХреЗ рдЬреЛрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реВрдВ ред рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рдЕрдиреБрднрд╡ рдирд┐рд░рд╛рд╢рд╛рдЬрдирдХ рд╣реЛрддрд╛ рд╣реИред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ (рдЬреЛ рдореЗрд░реЗ рдЕрдиреНрдп рд▓реЗрдЦ рдХрд╛ рдПрдХ рдирд┐: рд╢реБрд▓реНрдХ рдЕрдиреБрд╡рд╛рдж рд╣реИ ) рдореИрдВ рдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдХрд░реВрдВрдЧрд╛ рдФрд░ рдЗрд╕ рд╕реАрдорд╛ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдПрдХ рдХреЛрдб (рд╕реАрдзреА), рд╡рд┐рдЪрд╛рд░ рдФрд░ рдПрдХ рд╕реБрдЦрдж рдЕрдВрдд рдХреА рддрд░рд╣ рдХреБрдЫ рд╣реЛрдЧрд╛ред
рдкрд░рд┐рдЪрдп
рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рд░ рдХреЛрдИ рдЬрд╛рдирддрд╛ рд╣реИ, рд╣рд░ рджрд┐рди рдХрдИ рд▓реЛрдЧ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕реЗ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдкрдХрд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкрд░ рдХрдИ рдЕрдЪреНрдЫреЗ рд▓реЗрдЦ рд╣реИрдВ (рд╕рд░рд▓ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рд╕реНрдХрд┐рдк рдФрд░ рдЯреЗрдХ рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рд╡реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдлрд╝реАрд▓реНрдб рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВ, рдХреНрд╡реЗрд░реА рдХреИрд╢рд┐рдВрдЧ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░реЗрдВ) рдЕрдиреНрдп), рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕реНрдерд╛рдиреАрдп рд╕рдВрдЧреНрд░рд╣ рдФрд░ DbSet рдХрд╛ JOIN рд╡рд┐рд╖рдп рдЕрднреА рднреА рдПрдХ рдХрдордЬреЛрд░ рдмрд┐рдВрджреБ рд╣реИред
рдХрд╛рд░реНрдп
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдХреАрдорддреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ рдФрд░ рд▓реЗрдирджреЗрди рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреАрдорддреЛрдВ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдФрд░ рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рд╣реИред
var localData = GetDataFromApiOrUser(); var query = from p in context.Prices join s in context.Securities on p.SecurityId equals s.SecurityId join t in localData on new { s.Ticker, p.TradedOn, p.PriceSourceId } equals new { t.Ticker, t.TradedOn, t.PriceSourceId } select p; var result = query.ToList();
рдпрд╣ рдХреЛрдб рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ 6 рдореЗрдВ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЗрдХрд╛рдИ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдореЗрдВ - рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рдм рдХреБрдЫ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рддрд░рдл рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдм рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд▓рд╛рдЦреЛрдВ рд░рд┐рдХреЙрд░реНрдб рд╣реЛрдВрдЧреЗ - рдпрд╣ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдореИрдВ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рд╕рд░рд▓ рд╕реЗ рдЬрдЯрд┐рд▓ рддрдХред рдЕрдкрдиреЗ рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рднрдВрдбрд╛рд░ рд╕реЗ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ: C # , .net Core , EF Core рдФрд░ PostgreSQL ред
рдореИрдВрдиреЗ рдХреБрдЫ рдореАрдЯреНрд░рд┐рдХ рднреА рд╢реВрдЯ рдХрд┐рдП: рд╕рдордп рдмрд┐рддрд╛рдпрд╛ рдФрд░ рд╕реНрдореГрддрд┐ рдХреА рдЦрдкрддред рдЕрд╕реНрд╡реАрдХрд░рдг: рдпрджрд┐ рдкрд░реАрдХреНрд╖рдг 10 рдорд┐рдирдЯ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рддрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдореИрдВрдиреЗ рдЗрд╕реЗ рдмрд╛рдзрд┐рдд рдХрд░ рджрд┐рдпрд╛ (рдкреНрд░рддрд┐рдмрдВрдз рдКрдкрд░ рд╕реЗ рд╣реИ)ред рдЯреЗрд╕реНрдЯ рдорд╢реАрди рдЗрдВрдЯреЗрд▓ рдХреЛрд░ i5, 8 рдЬреАрдмреА рд░реИрдо, рдПрд╕рдПрд╕рдбреАред
рдбреАрдмреА рд╕реНрдХреАрдорд╛
рдХреЗрд╡рд▓ 3 рдЯреЗрдмрд▓: рдореВрд▓реНрдп , рдкреНрд░рддрд┐рднреВрддрд┐рдпрд╛рдВ рдФрд░ рдореВрд▓реНрдп рд╕реНрд░реЛрдд ред рдореВрд▓реНрдп - 10 рдорд┐рд▓рд┐рдпрди рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рд╣реИрдВред
рд╡рд┐рдзрд┐ 1. Naive
рдЖрдЗрдП рд╕рд░рд▓ рд╢реБрд░реВ рдХрд░реЗрдВ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
рд╡рд┐рдзрд┐ 1 рдХреЗ рд▓рд┐рдП рдХреЛрдб var result = new List<Price>(); using (var context = CreateContext()) { foreach (var testElement in TestData) { result.AddRange(context.Prices.Where( x => x.Security.Ticker == testElement.Ticker && x.TradedOn == testElement.TradedOn && x.PriceSourceId == testElement.PriceSourceId)); } }
рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╕рд░рд▓ рд╣реИ: рдПрдХ рд▓реВрдк рдореЗрдВ рд╣рдо рдПрдХ рд╕рдордп рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд░рд┐рдХреЙрд░реНрдб рдкрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдореА рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЗрд╕ рдХреЛрдб рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдлрд╛рдпрджрд╛ рд╣реИ - рд╕рд╛рджрдЧреАред рдФрд░ рдПрдХ рджреЛрд╖ рдХрдо рдЧрддрд┐ рд╣реИ: рднрд▓реЗ рд╣реА рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреЛрдИ рдЗрдВрдбреЗрдХреНрд╕ рд╣реЛ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд░ рдХрд░реЗрдЧрд╛ред рдореИрдЯреНрд░рд┐рдХреНрд╕ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ:

рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдХрдо рд╣реИред рдПрдХ рдмрдбрд╝реЗ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ 1 рдорд┐рдирдЯ рдХрд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдПрдХ рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП, рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рддреЗрдЬреА рд╕реЗ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рд╡рд┐рдзрд┐ 2: Naive рд╕рдорд╛рдирд╛рдВрддрд░
рдЖрдЗрдП рд╕рдорд╛рдирддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВред рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдХрдИ рдереНрд░реЗрдб рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред
рд╡рд┐рдзрд┐ 2 рдХреЗ рд▓рд┐рдП рдХреЛрдб var result = new ConcurrentBag<Price>(); var partitioner = Partitioner.Create(0, TestData.Count); Parallel.ForEach(partitioner, range => { var subList = TestData.Skip(range.Item1) .Take(range.Item2 - range.Item1) .ToList(); using (var context = CreateContext()) { foreach (var testElement in subList) { var query = context.Prices.Where( x => x.Security.Ticker == testElement.Ticker && x.TradedOn == testElement.TradedOn && x.PriceSourceId == testElement.PriceSourceId); foreach (var el in query) { result.Add(el); } } } });
рдкрд░рд┐рдгрд╛рдо:

рдЫреЛрдЯреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд▓рд┐рдП, рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд╣рд▓реА рд╡рд┐рдзрд┐ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рднреА рдзреАрдорд╛ рд╣реИред рдФрд░ рд╕рдмрд╕реЗ рдмрдбрд╝реЗ рдХреЗ рд▓рд┐рдП - 2 рдмрд╛рд░ рддреЗрдЬреА рд╕реЗред рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рдореЗрд░реА рдорд╢реАрди рдкрд░ 4 рдзрд╛рдЧреЗ рдЙрддреНрдкрдиреНрди рд╣реБрдП рдереЗ, рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ 4x рддреНрд╡рд░рдг рдирд╣реАрдВ рд╣реБрдЖред рдЗрд╕рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкрджреНрдзрддрд┐ рдореЗрдВ рдУрд╡рд░рд╣реЗрдб рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ: рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд╛рдЗрдб рдФрд░ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рджреЛрдиреЛрдВ рдкрд░ред рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдореЗрдВ рд╡реГрджреНрдзрд┐ рд╣реБрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдирд╣реАрдВред
рд╡рд┐рдзрд┐ 3: рдПрдХрд╛рдзрд┐рдХ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ
рд╕рдордп рдХреБрдЫ рдФрд░ рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдПрдХ рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХреЛ рдХрдо рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- рдЯрд┐рдХрд░ , рдкреНрд░рд╛рдЗрд╕рд╕реЛрд░реНрд╕рдЖрдИ рдФрд░ рдбреЗрдЯ рдХреЗ 3 рдЕрдиреВрдареЗ рд╕рдВрдЧреНрд░рд╣ рддреИрдпрд╛рд░ рдХрд░реЗрдВ
- рдЕрдиреБрд░реЛрдз рдЪрд▓рд╛рдПрдБ рдФрд░ 3 рдпреБрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
- рд╕реНрдерд╛рдиреАрдп рд╕реНрддрд░ рдкрд░ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВ
рд╡рд┐рдзрд┐ 3 рдХреЗ рд▓рд┐рдП рдХреЛрдб var result = new List<Price>(); using (var context = CreateContext()) {
рдпрд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рд╕рдордп рдФрд░ рд▓реМрдЯрд╛рдП рдЧрдП рдбреЗрдЯрд╛ рдХреА рдорд╛рддреНрд░рд╛ рдбреЗрдЯрд╛ рдкрд░ рд╣реА рдирд┐рд░реНрднрд░ рд╣реИ (рджреЛрдиреЛрдВ рдХреНрд╡реЗрд░реА рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ)ред рдпрд╣реА рд╣реИ, рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╡рд╛рдкрд╕ рдЖ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рд░рд┐рдХреЙрд░реНрдб рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ 100 рдЧреБрдирд╛ рдЕрдзрд┐рдХ)ред
рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдордЭрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд╛рд▓рд┐рдХрд╛ рд╣реИ:

рдпрд╣ рднреА рдорд╛рди рд▓реЗрдВ рдХрд┐ рдореБрдЭреЗ Ticker1 рдХреЗ рд▓рд┐рдП TradedOn = 2018-01-01 рдФрд░ TradedOn = 2018-01-02 рдХреЗ рд╕рд╛рде Ticker2 рдХреЗ рд▓рд┐рдП рдХреАрдорддреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рддрдм рдЯрд┐рдХрд░ рдХреЗ рд▓рд┐рдП рдЕрджреНрд╡рд┐рддреАрдп рдореВрд▓реНрдп = ( рдЯрд┐рдХрд░ 1 , рдЯрд┐рдХрд░ 2)
рдФрд░ TradedOn = ( 2018-01-01 , 2018-01-02 ) рдХреЗ рд▓рд┐рдП рдЕрджреНрд╡рд┐рддреАрдп рдореВрд▓реНрдп
рд╣рд╛рд▓рд╛рдВрдХрд┐, 4 рд░рд┐рдХреЙрд░реНрдб рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрди рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВред рдмреБрд░реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЬрд┐рддрдиреЗ рдЕрдзрд┐рдХ рдЦреЗрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЕрддрд┐рд░рд┐рдХреНрдд рд░рд┐рдХреЙрд░реНрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдЕрдзрд┐рдХ рд╣реЛрддреА рд╣реИред
рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ, рдЗрд╕ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рд░реВрдк рд╕реЗ рдЧреНрд░рд╛рд╣рдХ рдХреА рдУрд░ рд╕реЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдпрд╣реА рд╕рдмрд╕реЗ рдмрдбрд╝реА рдХрдореА рд╣реИред
рдореИрдЯреНрд░рд┐рдХреНрд╕ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ:

рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдкрд┐рдЫрд▓реЗ рд╕рднреА рддрд░реАрдХреЛрдВ рд╕реЗ рдЦрд░рд╛рдм рд╣реИред рдкрдврд╝реА рдЧрдИ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЕрдиреБрд░реЛрдзрд┐рдд рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдХрдИ рдЧреБрдирд╛ рдЕрдзрд┐рдХ рд╣реИред рдмрдбрд╝реЗ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдмрд╛рдзрд┐рдд рд╣реЛ рдЧрдП рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ 10 рдорд┐рдирдЯ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рддрдХ рдЪрд▓реЗред рдпрд╣ рддрд░реАрдХрд╛ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИред
рд╡рд┐рдзрд┐ 4. рдмрд┐рд▓реНрдбрд░ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░реЗрдВ
рдЪрд▓реЛ рдЗрд╕реЗ рджреВрд╕рд░реА рддрд░рдл рдЖрдЬрд╝рдорд╛рддреЗ рд╣реИрдВ: рдЕрдЪреНрдЫрд╛ рдкреБрд░рд╛рдирд╛ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ ред рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдирд┐рдореНрди рд░реВрдк рдореЗрдВ 1 рдмрдбрд╝реА рдХреНрд╡реЗрд░реА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:
тАж (.. AND .. AND ..) OR (.. AND .. AND ..) OR (.. AND .. AND ..) тАж
рдпрд╣ рдЖрд╢рд╛ рдХрд░рддрд╛ рд╣реИ рдХрд┐ 1 рдЕрдиреБрд░реЛрдз рдмрдирд╛рдиреЗ рдФрд░ 1 рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рдХреЛрдб:
рд╡рд┐рдзрд┐ 4 рдХреЗ рд▓рд┐рдП рдХреЛрдб var result = new List<Price>(); using (var context = CreateContext()) { var baseQuery = from p in context.Prices join s in context.Securities on p.SecurityId equals s.SecurityId select new TestData() { Ticker = s.Ticker, TradedOn = p.TradedOn, PriceSourceId = p.PriceSourceId, PriceObject = p }; var tradedOnProperty = typeof(TestData).GetProperty("TradedOn"); var priceSourceIdProperty = typeof(TestData).GetProperty("PriceSourceId"); var tickerProperty = typeof(TestData).GetProperty("Ticker"); var paramExpression = Expression.Parameter(typeof(TestData)); Expression wholeClause = null; foreach (var td in TestData) { var elementClause = Expression.AndAlso( Expression.Equal( Expression.MakeMemberAccess( paramExpression, tradedOnProperty), Expression.Constant(td.TradedOn) ), Expression.AndAlso( Expression.Equal( Expression.MakeMemberAccess( paramExpression, priceSourceIdProperty), Expression.Constant(td.PriceSourceId) ), Expression.Equal( Expression.MakeMemberAccess( paramExpression, tickerProperty), Expression.Constant(td.Ticker)) )); if (wholeClause == null) wholeClause = elementClause; else wholeClause = Expression.OrElse(wholeClause, elementClause); } var query = baseQuery.Where( (Expression<Func<TestData, bool>>)Expression.Lambda( wholeClause, paramExpression)).Select(x => x.PriceObject); result.AddRange(query); }
рдХреЛрдб рдкрд┐рдЫрд▓реЗ рддрд░реАрдХреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдирд┐рдХрд▓рд╛ред рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдорд╛рдг рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдФрд░ рд╕рдмрд╕реЗ рддреЗрдЬрд╝ рдСрдкрд░реЗрд╢рди рдирд╣реАрдВ рд╣реИред
рдореЗрдЯреНрд░рд┐рдХреНрд╕:

рдкрд┐рдЫрд▓реЗ рдкрджреНрдзрддрд┐ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрд╕реНрдерд╛рдпреА рдкрд░рд┐рдгрд╛рдо рдФрд░ рднреА рдЦрд░рд╛рдм рдереЗред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди рдУрд╡рд░рд╣реЗрдб рдФрд░ рдЬрдм рдкреЗрдбрд╝ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рдирд╛ рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд▓рд╛рдн рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реЛ рдЧрдпрд╛ред
рд╡рд┐рдзрд┐ 5: рд╕рд╛рдЭрд╛ рдбреЗрдЯрд╛ рддрд╛рд▓рд┐рдХрд╛ рд╕рд╛рдЭрд╛ рдХреА рдЧрдИ
рдЪрд▓реЛ рдПрдХ рдФрд░ рд╡рд┐рдХрд▓реНрдк рдЖрдЬрд╝рдорд╛рдПрдБ:
рдореИрдВрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдирдИ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдИ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рдЕрдиреБрд░реЛрдз рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рд▓рд┐рдЦреВрдВрдЧрд╛ ( рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдореБрдЭреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХ рдирдпрд╛ рдбреАрдмреАрдПрд╕рд╕реЗрдЯ рдЪрд╛рд╣рд┐рдП )ред
рдЕрдм, рдЖрдк рдХреА рдЬрд░реВрд░рдд рд╣реИ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП:
- рд▓реЗрди-рджреЗрди рд╢реБрд░реВ рдХрд░реЗрдВ
- рдХреНрд╡реЗрд░реА рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рдирдИ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдЕрдкрд▓реЛрдб рдХрд░реЗрдВ
- рдХреНрд╡реЗрд░реА рдХреЛ рд╕реНрд╡рдпрдВ рдЪрд▓рд╛рдПрдВ (рдирдИ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)
- рд▓реЗрди-рджреЗрди рд╡рд╛рдкрд╕ рдХрд░реЗрдВ (рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рддрд╛рд▓рд┐рдХрд╛ рд╕рд╛рдлрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП)
рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
рд╡рд┐рдзрд┐ 5 рдХреЗ рд▓рд┐рдП рдХреЛрдб var result = new List<Price>(); using (var context = CreateContext()) { context.Database.BeginTransaction(); var reducedData = TestData.Select(x => new SharedQueryModel() { PriceSourceId = x.PriceSourceId, Ticker = x.Ticker, TradedOn = x.TradedOn }).ToList();
рдкрд╣рд▓реА рдореАрдЯреНрд░рд┐рдХ:

рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛! рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рднреА рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рд▓реЗрдирджреЗрди рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдПрдХ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рдЪреВрдВрдХрд┐ рдпрд╣ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдореМрдЬреВрджрд╛ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ, рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреА рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ: рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдиреЗ, рдЬреЛрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдХреНрд╡реЗрд░реА рдмрдирд╛рдиреЗ рдФрд░ рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдорд╣рддреНрд╡рдкреВрд░реНрдг рдиреБрдХрд╕рд╛рди рд╣реИрдВ:
- рдЖрдкрдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдиреА рд╣реЛрдЧреА
- рд▓реЗрди-рджреЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдФрд░ рдЙрди рдкрд░ DBMS рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдмрд░реНрдмрд╛рдж рдХрд░рдирд╛)
- рдФрд░ рдмрд╣реБрдд рд╡рд┐рдЪрд╛рд░ рд╣реИ рдХрд┐ рдЖрдк рдХреБрдЫ рд▓рд┐рдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдЬрдм рдЖрдк рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдЕрдЬреАрдм рд▓рдЧ рд░рд╣рд╛ рд╣реИред рдФрд░ рдкрдврд╝реЗрдВ рдкреНрд░рддрд┐рдХреГрддрд┐ рдкрд░, рдпрд╣ рд╕рд┐рд░реНрдл рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдФрд░ рдмрд╛рдХреА рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡рд┐рдзрд┐ 6. рдореЗрдореЛрд░реАрдЬреЙрдЗрди рдПрдХреНрд╕рдЯреЗрдВрд╢рди
рдЕрдм рдЖрдк рдкрд┐рдЫрд▓реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рдЪрд╛рд░ рд╣реИрдВ:
- рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ, рдЖрдк рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрд░реНрдерд╛рддреН, рд╢реЗрдпрд░реНрдб_рдХреНрд╡реЗрд░реА_рдбреЗрдЯрд╛ рдЬреИрд╕реЗ рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдПрдВ , рдФрд░ рдЗрд╕рдореЗрдВ рдХрдИ рдЧрд╛рдЗрдб рдлрд╝реАрд▓реНрдб, рдХрдИ рд▓реЙрдиреНрдЧ , рдХрдИ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЖрджрд┐ рдЬреЛрдбрд╝реЗрдВред рд╕рд░рд▓ рдирд╛рдо рд▓рд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ: Guid1 , Guid2 , String1 , Long1 , Date2 , рдЖрджрд┐ред рдлрд┐рд░ рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ 95% рдХреНрд╡реЗрд░реА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдВрдкрддреНрддрд┐ рдХреЗ рдирд╛рдо рдмрд╛рдж рдореЗрдВ рдЪреБрдирд┐рдВрджрд╛ рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "рд╕рдорд╛рдпреЛрдЬрд┐рдд" рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
- рдЖрдЧреЗ рдЖрдкрдХреЛ share_query_data рдХреЗ рд▓рд┐рдП рдПрдХ DbSet рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ ред
- рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╡реИрд▓реНрдпреВ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП? рдпрд╣реА рд╣реИ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдЕрдВрддрд┐рдо SQL рдХреНрд╡реЗрд░реА рдореЗрдВ, share_query_data рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рдмрдЬрд╛рдп , VALUES рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдкреАрд▓ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ?
- рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдореЗрдВ - рдмрд╕ FromSql рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ред
- Entity Framework 6 рдореЗрдВ - рдЖрдкрдХреЛ DbInterception рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ - рдЕрд░реНрдерд╛рдд, рдирд┐рд╖реНрдкрд╛рджрди рд╕реЗ рдкрд╣рд▓реЗ VALUES рдирд┐рд░реНрдорд╛рдг рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдЙрддреНрдкрдиреНрди SQL рдХреЛ рдмрджрд▓ рджреЗрдВред рдпрд╣ рдПрдХ рд╕реАрдорд╛ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рджреЗрдЧрд╛: рдПрдХ рд╣реА рдЕрдиреБрд░реЛрдз рдореЗрдВ, рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╡рд╛рд▓реНрд╡ рдирд┐рд░реНрдорд╛рдг рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛!
- рдЪреВрдБрдХрд┐ рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдирд╣реАрдВ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ рд╕рд╛рдЭрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ share_query_data рдЯреЗрдмрд▓ рдорд┐рд▓рддрд╛ рд╣реИ, рдХреНрдпрд╛ рдЗрд╕рдХреА рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ? рдЙрддреНрддрд░: рд╣рд╛рдБ, рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди DbSet рдХреА рдЕрднреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд╕реНрдХреАрдо рдХрд╛ рдкрддрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП DbSet рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рдкреНрд░реЗрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХрд┐ рдпрд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИред
IEnumerable рдХреЛ IQueryable рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдмрджрд▓реЗрдВ- рдЗрдирдкреБрдЯ рдХреЛ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рд╕рдВрдЧреНрд░рд╣ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ:
class SomeQueryData { public string Ticker {get; set;} public DateTimeTradedOn {get; set;} public int PriceSourceId {get; set;} }
- рд╣рдорд╛рд░реЗ рдкрд╛рд╕ String1 , String2 , Date1 , Long1 , рдЖрджрд┐ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдирд┐рдкрдЯрд╛рди DbSet рд╣реИрдВ
- рдЯрд┐рдХрд░ рдХреЛ String1 , TradedOn in Date1 рдФрд░ LongS1 рдореЗрдВ PriceSourceId рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП ( рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЗрдВрдЯ рдореЗрдВ рдореИрдкреНрд╕, рддрд╛рдХрд┐ рдЗрдВрдЯ рдФрд░ рд▓реЙрдиреНрдЧ рдЕрд▓рдЧ рдХреЗ рд▓рд┐рдП рдлрд╝реАрд▓реНрдб рди рдмрдирд╛рдПрдВ)
- рдлрд┐рд░ FromSql + VALUES рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:
var query = context.QuerySharedData.FromSql( "SELECT * FROM ( VALUES (1, 'Ticker1', @date1, @id1), (2, 'Ticker2', @date2, @id2) ) AS __gen_query_data__ (id, string1, date1, long1)")
- рдЕрдм рдЖрдк рдПрдХ рдкреНрд░рдХреНрд╖реЗрдкрдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ IQueryable рд▓реМрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЗрдирдкреБрдЯ рдкрд░ рдерд╛:
return query.Select(x => new SomeQueryData() { Ticker = x.String1, TradedOn = x.Date1, PriceSourceId = (int)x.Long1 });
рдореИрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЗрд╕реЗ NuGet рдкреИрдХреЗрдЬ EntityFrameworkCore.MemoryJoin ( рдХреЛрдб рднреА рдЙрдкрд▓рдмреНрдз рд╣реИ) рдХреЗ рд░реВрдк рдореЗрдВ рдбрд┐рдЬрд╛рдЗрди рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛ред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдирд╛рдо рдореЗрдВ рдХреЛрд░ рд╢рдмреНрдж рд╢рд╛рдорд┐рд▓ рд╣реИ, рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ 6 рднреА рд╕рдорд░реНрдерд┐рдд рд╣реИред рдореИрдВрдиреЗ рдЗрд╕реЗ MemoryJoin рдХрд╣рд╛, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ VALUES рдирд┐рд░реНрдорд╛рдг рдореЗрдВ DBMS рдХреЛ рд╕реНрдерд╛рдиреАрдп рдбреЗрдЯрд╛ рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдкрд░ рд╕рднреА рдХрд╛рдо рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
рдХреЛрдб рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:
рд╡рд┐рдзрд┐ 6 рдХреЗ рд▓рд┐рдП рдХреЛрдб var result = new List<Price>(); using (var context = CreateContext()) {
рдореЗрдЯреНрд░рд┐рдХреНрд╕:

рдпрд╣ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдЖрдЬрдорд╛рдпрд╛ рдЧрдпрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рдХреЛрдб рдмрд╣реБрдд рд╕рд░рд▓ рдФрд░ рд╕реАрдзрд╛ рдерд╛, рдФрд░ рдЙрд╕реА рд╕рдордп рд░реАрдб рд░реЗрдкреНрд▓рд┐рдХрд╛ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛ред
3 рддрддреНрд╡реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдЕрдиреБрд░реЛрдз рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг SELECT "p"."PriceId", "p"."ClosePrice", "p"."OpenPrice", "p"."PriceSourceId", "p"."SecurityId", "p"."TradedOn", "t"."Ticker", "t"."TradedOn", "t"."PriceSourceId" FROM "Price" AS "p" INNER JOIN "Security" AS "s" ON "p"."SecurityId" = "s"."SecurityId" INNER JOIN ( SELECT "x"."string1" AS "Ticker", "x"."date1" AS "TradedOn", CAST("x"."long1" AS int4) AS "PriceSourceId" FROM ( SELECT * FROM ( VALUES (1, @__gen_q_p0, @__gen_q_p1, @__gen_q_p2), (2, @__gen_q_p3, @__gen_q_p4, @__gen_q_p5), (3, @__gen_q_p6, @__gen_q_p7, @__gen_q_p8) ) AS __gen_query_data__ (id, string1, date1, long1) ) AS "x" ) AS "t" ON (("s"."Ticker" = "t"."Ticker") AND ("p"."PriceSourceId" = "t"."PriceSourceId")
рдпрд╣рд╛рдВ рдЖрдк рдпрд╣ рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдореЙрдбрд▓ (рдлрд╝реАрд▓реНрдб String1 , Date1 , Long1 рдХреЗ рд╕рд╛рде ) рд╕реЗрд▓реЗрдХреНрдЯ рдореЗрдВ рдЙрдкрдпреЛрдЧ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдХреЛрдб рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ (рдлрд╝реАрд▓реНрдб Ticker , TradedOn , PriceSourceId рдХреЗ рд╕рд╛рде )ред
рд╕рднреА рдХрд╛рд░реНрдп SQL рд╕рд░реНрд╡рд░ рдкрд░ 1 рдХреНрд╡реЗрд░реА рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдпрд╣ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╕реБрдЦрдж рдЕрдВрдд рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмрд╛рдд рдХреА рдереАред рдлрд┐рд░ рднреА, рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдФрд░ рдирд┐рдореНрди рдЪрд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд DbSet рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдБрдХрд┐ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ )
- рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдореЙрдбрд▓ рдореЗрдВ, рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, 3 рдкреНрд░рдХрд╛рд░ рдХреЗ рдЧрд╛рдЗрдб , рд╕реНрдЯреНрд░рд┐рдВрдЧ , рдбрдмрд▓ , рд▓реЙрдиреНрдЧ , рдбреЗрдЯ , рдЖрджрд┐ рдШреЛрд╖рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ 95% рдЕрдиреБрд░реЛрдз рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдпрджрд┐ рдЖрдк FromLocalList рдореЗрдВ 20 рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЗ рд╕рд╛рде рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рд╕рдВрдЧреНрд░рд╣ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ , рддреЛ рдПрдХ рдПрдХреНрд╕реЗрдкреНрд╢рди рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдпрд╣ рдХрд╣рддреЗ рд╣реБрдП рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реИред рдпрд╣ рдПрдХ рдирд░рдо рдкреНрд░рддрд┐рдмрдВрдз рд╣реИ рдФрд░ рдЗрд╕реЗ рджрд░рдХрд┐рдирд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЖрдк рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣рд╛рдВ рдХрдо рд╕реЗ рдХрдо 100 рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдзрд┐рдХ рдХреНрд╖реЗрддреНрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзреАрдореА рд╣реИрдВред
- рдореЗрд░реЗ рд▓реЗрдЦ рдореЗрдВ рдЕрдзрд┐рдХ рддрдХрдиреАрдХреА рд╡рд┐рд╡рд░рдг рд╡рд░реНрдгрд┐рдд рд╣реИрдВред
рдирд┐рд╖реНрдХрд░реНрд╖
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ JOIN рд╕реНрдерд╛рдиреАрдп рд╕рдВрдЧреНрд░рд╣ рдФрд░ DbSet рд╡рд┐рд╖рдп рдкрд░ рдЕрдкрдиреЗ рд╡рд┐рдЪрд╛рд░ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдПред рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ VALUES рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдореЗрд░рд╛ рд╡рд┐рдХрд╛рд╕ рд╕рдореБрджрд╛рдп рдХреЗ рд▓рд┐рдП рд░реВрдЪрд┐рдХрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдХрдо рд╕реЗ рдХрдо рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдерд╛ рдЬрдм рдореИрдВрдиреЗ рдЦреБрдж рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдерд╛ред рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдЗрд╕ рдкрджреНрдзрддрд┐ рдиреЗ рдореБрдЭреЗ рдЕрдкрдиреА рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдХрдИ рдкреНрд░рджрд░реНрд╢рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХреА, рд╢рд╛рдпрдж рдпрд╣ рдЖрдкрдХреА рднреА рдорджрдж рдХрд░реЗрдЧреАред
рдХреЛрдИ рдХрд╣реЗрдЧрд╛ рдХрд┐ рдореЗрдореЛрд░реАрдЬреЙрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╣реБрдд рдЕрдзрд┐рдХ " рд╕рдВрдХреНрд╖рд┐рдкреНрдд " рд╣реИ рдФрд░ рдЗрд╕реЗ рдФрд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рддрдм рддрдХ рдЖрдкрдХреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдореБрдЭреЗ рдмрд╣реБрдд рд╕рдВрджреЗрд╣ рдерд╛ рдФрд░ рд▓рдЧрднрдЧ рдПрдХ рд╕рд╛рд▓ рддрдХ рдореИрдВрдиреЗ рдпрд╣ рд▓реЗрдЦ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ред рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рдЖрд╕рд╛рди рдХрд╛рдо рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ (рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рджрд┐рди рд╣реЛрдЧрд╛), рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рднреА рдХрд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдиреБрдХреВрд▓рди рдХрднреА рднреА рдЬреВрдирд┐рдпрд░реНрд╕ рдХрд╛ рдХрд╛рдо рдирд╣реАрдВ рд░рд╣рд╛ рд╣реИред рдЕрдиреБрдХреВрд▓рди рдХреЛ рд╣рдореЗрд╢рд╛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рдЙрдкрдХрд░рдг рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдФрд░ рдЕрдЧрд░ ~ 8 рдЧреБрдирд╛ ( Naive Parallel vs MemoryJoin ) рджреНрд╡рд╛рд░рд╛ рддреНрд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИ, рддреЛ рдореИрдВ 2 рдЕрдВрдХ рдФрд░ рдкреНрд░рд▓реЗрдЦрди рдорд╛рд╕реНрдЯрд░ рдХрд░реВрдВрдЧрд╛ред
рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЖрд░реЗрдЦ:
рд╕рдордп рдмрд┐рддрд╛рдпрд╛ред рдХреЗрд╡рд▓ 4 рд╡рд┐рдзрд┐рдпреЛрдВ рдиреЗ 10 рдорд┐рдирдЯ рд╕реЗ рдХрдо рд╕рдордп рдореЗрдВ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рдХрд┐рдпрд╛, рдФрд░ рдореЗрдореЛрд░реАрдЬреЛрди рдПрдХрдорд╛рддреНрд░ рдРрд╕рд╛ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рдиреЗ 10 рд╕реЗрдХрдВрдб рд╕реЗ рдХрдо рд╕рдордп рдореЗрдВ рдХрд╛рд░реНрдп рдкреВрд░рд╛ рдХрд┐рдпрд╛ рд╣реИред

рдореЗрдореЛрд░реА рдХреА рдЦрдкрддред рдорд▓реНрдЯреАрдкрд▓ рдХрдВрдЯреЗрд╕реНрдЯреЗрдВрдЯреНрд╕ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рддрд░реАрдХреЛрдВ рдореЗрдВ рд▓рдЧрднрдЧ рдПрдХ рд╣реА рдореЗрдореЛрд░реА рдЦрдкрдд рджрд┐рдЦрд╛рдИ рдЧрдИред рдпрд╣ рдбреЗрдЯрд╛ рдХреА рд░рд╛рд╢рд┐ рд╡рд╛рдкрд╕ рдЖрдиреЗ рдХреЗ рдХрд╛рд░рдг рд╣реИред

рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!