рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдХреЛ рдЧрддрд┐ рджреЗрдирд╛

рд▓рд╛рд▓рдЪреА рдордд рдмрдиреЛ!


рдбреЗрдЯрд╛ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдПрдХ рд╕рдордп рдореЗрдВ рдЬрд┐рддрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрддрдиреЗ рд╣реА рдЪреБрдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рд╕рднреА рдбреЗрдЯрд╛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рди рдХрд░реЗрдВ!

рдЧрд▓рдд:

using var ctx = new EFCoreTestContext(optionsBuilder.Options);                
//    ID  ,       !
ctx.FederalDistricts.Select(x=> new { x.ID, x.Name, x.ShortName }).ToList();

рд╕рд╣реА рдврдВрдЧ рд╕реЗ:

using var ctx = new EFCoreTestContext(optionsBuilder.Options);  
//     ID     !
ctx.FederalDistricts.Select(x=> new { x.Name, x.ShortName }).ToList();
ctx.FederalDistricts.Select(x => new MyClass { Name = x.Name, ShortName = x.ShortName }).ToList();


рдЧрд▓рдд:

var blogs = context.Blog.ToList(); //       . ?
//     ?
var somePost = blogs.FirstOrDefault(x=>x.Title.StartWidth(тАЬHello world!тАЭ));

рд╕рд╣реА рдврдВрдЧ рд╕реЗ:

var somePost = context.Blog.FirstOrDefault(x=>x.Title.StartWidth(тАЬHello world!тАЭ));

рдПрдХреАрдХреГрдд рдбреЗрдЯрд╛ рд╕рддреНрдпрд╛рдкрди рддрдм рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рдХреЛрдИ рдХреНрд╡реЗрд░реА рдХреБрдЫ рд░рд┐рдХреЙрд░реНрдб рд▓реМрдЯрд╛рддреА рд╣реИред

рдЧрд▓рдд:


var blogs = context.Blogs.Where(blog => StandardizeUrl(blog.Url).Contains("dotnet")).ToList();

public static string StandardizeUrl(string url)
{
    url = url.ToLower();
    if (!url.StartsWith("http://"))
    {
        url = string.Concat("http://", url);
    }
    return url;
}

рд╕рд╣реА рдврдВрдЧ рд╕реЗ:

var blogs = context.Blogs.AsEnumerable().Where(blog => StandardizeUrl(blog.Url).Contains("dotnet")).ToList();
 
//  
var blogs = context.Blogs.Where(blog => blog.Contains("dotnet"))
    .OrderByDescending(blog => blog.Rating)
    .Select(blog => new
    {
        Id = blog.BlogId,
        Url = StandardizeUrl(blog.Url)
    })
    .ToList();

рд╡рд╛рд╣, рд╡рд╛рд╣, рд╡рд╛рд╣, рддрд╛рд▓реА рдмрдЬреАред

рдпрд╣ LINQ рддрдХрдиреАрдХреЛрдВ рдХреЗ рдЖрдкрдХреЗ рдЬреНрдЮрд╛рди рдХреЛ рдереЛрдбрд╝рд╛ рддрд╛рдЬрд╝рд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

рдЖрдЗрдП рджреЗрдЦреЗрдВ ToList AsEnumerable AsQueryable рдХреЗ рдмреАрдЪ рдЕрдВрддрд░


рд╕реЛ рдЯрд╛рд▓рд╕реНрдЯ

  • .
  • .ToList() (lazy loading), .

AsEnumerable

  • (lazy loading)
  • : Func <TSource, bool>
  • ( Where/Take/Skip , , select * from Table1,
  • , N )
  • : Linq-to-SQL + Linq-to-Object.
  • IEnumerable (lazy loading).

AsQueryable

  • (lazy loading)
  • :
    AsQueryable(IEnumerable)  AsQueryable<TElement>(IEnumerable<TElement>) 

  • Expression T-SQL ( ), .
  • DbSet ( Entity Framework) AsQueryable .
  • , Take(5) ┬лselect top 5 * SQL┬╗ . , SQL , . AsQueryable() , AsEnumerable() T-SQL Linq .
  • рдпрджрд┐ рдЖрдк рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреНрд╡реЗрд░реА рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдЪрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдмреЗрд╣рддрд░ рд╣реЛ рд╕рдХрддреА рд╣реИ, рддреЛ AsQueryable рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред


рд╕рдмрд╕реЗ рд╕рд░рд▓ рдорд╛рдорд▓реЗ рдореЗрдВ AsQueryable рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:

public IEnumerable<EmailView> GetEmails(out int totalRecords, Guid? deviceWorkGroupID,
                DateTime? timeStart, DateTime? timeEnd, string search, int? confirmStateID, int? stateTypeID, int? limitOffset, int? limitRowCount, string orderBy, bool desc)
        {
            var r = new List<EmailView>();

            using (var db = new GJobEntities())
            {
                var query = db.Emails.AsQueryable();

                if (timeStart != null && timeEnd != null)
                {
                    query = query.Where(p => p.Created >= timeStart && p.Created <= timeEnd);
                }

                if (stateTypeID != null && stateTypeID > -1)
                {
                    query = query.Where(p => p.EmailStates.OrderByDescending(x => x.AtTime).FirstOrDefault().EmailStateTypeID == stateTypeID);
                }


                if (confirmStateID != null && confirmStateID > -1)
                {
                    var boolValue = confirmStateID == 1 ? true : false;
                    query = query.Where(p => p.IsConfirmed == boolValue);
                }

                if (!string.IsNullOrEmpty(search))
                {
                    search = search.ToLower();
                    query = query.Where(p => (p.Subject + " " + p.CopiesEmails + " " + p.ToEmails + " " + p.FromEmail + " " + p.Body)
                                        .ToLower().Contains(search));
                }

                if (deviceWorkGroupID != Guid.Empty)
                {
                    query = query.Where(x => x.SCEmails.FirstOrDefault().SupportCall.Device.DeviceWorkGroupDevices.FirstOrDefault(p => p.DeviceWorkGroupID == deviceWorkGroupID) != null);
                }

                totalRecords = query.Count();
                query = query.OrderByDescending(p => p.Created);
                if (limitOffset.HasValue)
                {
                    query = query.Skip(limitOffset.Value).Take(limitRowCount.Value);
                }
                var items = query.ToList(); //    

                foreach (var item in items)
                {
                    var n = new EmailView
                    {
                        ID = item.ID,
                        SentTime = item.SentTime,
                        IsConfirmed = item.IsConfirmed,
                        Number = item.Number,
                        Subject = item.Subject,
                        IsDeleted = item.IsDeleted,
                        ToEmails = item.ToEmails,
                        Created = item.Created,
                        CopiesEmails = item.CopiesEmails,
                        FromEmail = item.FromEmail,
                    };

                    //     - 

                    r.Add(n);
                }
            }

            return r;
        }


рд╕рд╛рдзрд╛рд░рдг рдкрдврд╝рдиреЗ рдХрд╛ рдЬрд╛рджреВ


рдпрджрд┐ рдЖрдкрдХреЛ рдбреЗрдЯрд╛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдмрд╕ .AsNoTracking () рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред

рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдирдореВрдирд╛ рд▓реЗрдирд╛

var blogs = context.Blogs.ToList();

рдЬрд▓реНрджреА рд▓рд╛рдиреЗ (рдХреЗрд╡рд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП)

var blogs = context.Blogs.AsNoTracking().ToList();

рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдереЛрдбрд╝рд╛ рдЧрд░реНрдо рд╣реЛ рдЧрдП рд╣реИрдВ?

рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдХрд╛рд░


рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рднреВрд▓ рдЧрдП рд╣реИрдВ рдХрд┐ рдЖрд▓рд╕реА рд▓реЛрдбрд┐рдВрдЧ рдХреНрдпрд╛ рд╣реИ ред

рдЖрд▓рд╕реА рд▓реЛрдбрд┐рдВрдЧ (рдЖрд▓рд╕реА рд▓реЛрдбрд┐рдВрдЧ) рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреА рд╕рдВрдкрддреНрддрд┐ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рджреМрд░рд╛рди рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдкрд╛рд░рджрд░реНрд╢реА рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдФрд░ рдЕрдзрд┐рдХ рдкрдврд╝реЗрдВ рдпрд╣рд╛рдБ ред

рдФрд░ рд╕рд╛рде рд╣реА, рдореИрдВ рдЖрдкрдХреЛ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реЛрдбрд┐рдВрдЧ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдХреА рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВред

рд╕рдХреНрд░рд┐рдп рд▓реЛрдб (рдИрдЧрд░ рд▓реЛрдбрд┐рдВрдЧ) рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрдиреБрд░реЛрдз рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

using (var context = new BloggingContext())
{
    var blogs = context.Blogs
        .Include(blog => blog.Posts)
            .ThenInclude(post => post.Author)
                .ThenInclude(author => author.Photo)
        .Include(blog => blog.Owner)
            .ThenInclude(owner => owner.Photo)
        .ToList();
}

рдзреНрдпрд╛рди! рд╕рдВрд╕реНрдХрд░рдг EF Core 3.0.0 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рдорд┐рд▓ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд JOIN рд╕рдВрдмрдВрдзрдХ рдкреНрд░рджрд╛рддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди SQL рдХреНрд╡реЗрд░реА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ , рдЬрдмрдХрд┐ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдЕрддрд┐рд░рд┐рдХреНрдд SQL рдХреНрд╡реЗрд░реА рдЙрддреНрдкрдиреНрдиред рдпрд╣ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдмреЗрд╣рддрд░ рдпрд╛ рдмреЗрд╣рддрд░ рдХреЗ рд▓рд┐рдП рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдмрд╣реБрдд рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдмрдпрд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде LINQ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ LINQ рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд╕реНрдкрд╖реНрдЯ рд▓реЛрдбрд┐рдВрдЧ (рд╕реНрдкрд╖реНрдЯ рд▓реЛрдбрд┐рдВрдЧ) рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрд╛рдж рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

using (var context = new BloggingContext())
{
    var blog = context.Blogs
        .Single(b => b.BlogId == 1);

    var goodPosts = context.Entry(blog)
        .Collection(b => b.Posts)
        .Query()
        .Where(p => p.Rating > 3)
        .ToList();
}

рдЭрдЯрдХрд╛ рдФрд░ рд╕рдлрд▓рддрд╛! рдЖрдЧреЗ рдмрдврд╝рддреЗ рд░рд╣рдирд╛?

рдФрд░ рднреА рддреЗрдЬреА рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ?


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

(1) рдПрдордПрд╕ SQL тАЛтАЛрд╕рд░реНрд╡рд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдЕрдиреБрдХреНрд░рдорд┐рдд рджреГрд╢реНрдп

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

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

рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХ рд╕реВрдЪрдХрд╛рдВрдХ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд▓рд╛рдЧрдд рд╣реИред рдпрджрд┐ рд╣рдо рдПрдХ рдЕрдиреБрдХреНрд░рдорд┐рдд рджреГрд╢реНрдп рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рдмреЗрд╕ рдЯреЗрдмрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рдмрджрд▓рддреЗ рд╣реИрдВ, рддреЛ SQL рд╕рд░реНрд╡рд░ рдХреЛ рдЗрди рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рди рдХреЗрд╡рд▓ рд╕реВрдЪрдХрд╛рдВрдХ рд░рд┐рдХреЙрд░реНрдб рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдмрд▓реНрдХрд┐ рджреГрд╢реНрдп рдореЗрдВ рд╕реВрдЪрдХрд╛рдВрдХ рд░рд┐рдХреЙрд░реНрдб рднреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдФрд░ рдЙрджреНрдпрдореЛрдВ рдХреЗ рд▓рд┐рдП SQL рд╕рд░реНрд╡рд░ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ, рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝рд░ рдЙрди рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреНрд░рдорд┐рдд рджреГрд╢реНрдп рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, SQL рд╕рд░реНрд╡рд░ рдХреЗ рдЕрдиреНрдп рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ, рдХреНрд╡реЗрд░реА рдореЗрдВ рдЕрдиреБрдХреНрд░рдорд┐рдд рджреГрд╢реНрдп рд╢рд╛рдорд┐рд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рджреГрд╢реНрдп рдореЗрдВ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХреЗ рд▓рд┐рдП NOEXPAND рд╕рдВрдХреЗрдд рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

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

рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?


рд╣рд╛рдБ! рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬрд╣рд╛рдБ рднреА рд╕рдВрднрд╡ рд╣реЛ! рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

public void Do()
{
    var myTask = GetFederalDistrictsAsync ();
    foreach (var item in myTask.Result)
    {
         // 
    }
}

public async Task<List<FederalDistrict>> GetFederalDistrictsAsync()
{
    var conn = configurationRoot.GetConnectionString("EFCoreTestContext");
    optionsBuilder.UseSqlServer(conn);
    using var context = new EFCoreTestContext(optionsBuilder.Options);
    return await context.FederalDistricts.ToListAsync();
}

рдФрд░ рд╣рд╛рдБ, рдХреНрдпрд╛ рдЖрдк рдЙрддреНрдкрд╛рджрдХрддрд╛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рднреВрд▓ рдЧрдП рд╣реИрдВ? Buum!

return await context.FederalDistricts.<b>AsNoTracking()</b>.ToListAsync();


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

рдФрд░ рдореБрдЭреЗ ASP .NET рдХреЛрд░ рдореЗрдВ рдПрдХ рджреГрд╢реНрдп рдШрдЯрдХ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЗрд╕реЗ рджреЗрдиреЗ рджреЗрдВ :

//  
public class PopularPosts : ViewComponent
    {
        private readonly IStatsRepository _statsRepository;

        public PopularPosts(IStatsRepository statsRepository)
        {
            _statsRepository = statsRepository;
        }

        public async Task<IViewComponentResult> InvokeAsync()
        {
           //         -
            var federalDistricts = await _statsRepository.GetFederalDistrictsAsync(); 
            var model = new TablePageModel()
            {
                FederalDistricts = federalDistricts,
            };

            return View(model);
        }
    }
    // 
    
    /// <summary>
    ///  -   .... -
    /// </summary>
    public interface IStatsRepository
    {
        /// <summary>
        ///        
        /// </summary>
        /// <returns></returns>
        IEnumerable<FederalDistrict> FederalDistricts();

        /// <summary>
        ///        
	/// !!!
        /// </summary>
        /// <returns></returns>
        Task<List<FederalDistrict>> GetFederalDistrictsAsync();
    }	
	
    /// <summary>
    /// -   .... -
    /// </summary>
    public class StatsRepository : IStatsRepository
    {
        private readonly DbContextOptionsBuilder<EFCoreTestContext>
            optionsBuilder = new DbContextOptionsBuilder<EFCoreTestContext>();
        private readonly IConfigurationRoot configurationRoot;

        public StatsRepository()
        {
            IConfigurationBuilder configurationBuilder = new ConfigurationBuilder()
                    .SetBasePath(Environment.CurrentDirectory)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            configurationRoot = configurationBuilder.Build();
        }

        public async Task<List<FederalDistrict>> GetFederalDistrictsAsync()
        {
            var conn = configurationRoot.GetConnectionString("EFCoreTestContext");
            optionsBuilder.UseSqlServer(conn);
            using var context = new EFCoreTestContext(optionsBuilder.Options);
            return await context.FederalDistricts.Include(x => x.FederalSubjects).ToListAsync();
        }

        public IEnumerable<FederalDistrict> FederalDistricts()
        {
            var conn = configurationRoot.GetConnectionString("EFCoreTestContext");
            optionsBuilder.UseSqlServer(conn);

            using var ctx = new EFCoreTestContext(optionsBuilder.Options);
            return ctx.FederalDistricts.Include(x => x.FederalSubjects).ToList();
        }
    }

   //         Home\Index 
    <div id="tableContainer">
            @await Component.InvokeAsync("PopularPosts")
     </div>
  //   HTML      Shared\Components\PopularPosts\Default.cshtml



рдореБрдЭреЗ рдпрд╛рдж рджрд┐рд▓рд╛рдПрдВ рдЬрдм рдПрдВрдЯрд┐рдЯреА рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛрд░ рдореЗрдВ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

LINQ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯреНрд╕ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░, рдЖрдк рдмрд╕ рдореЗрдореЛрд░реА рдореЗрдВ рдПрдХ рдХреНрд╡реЗрд░реА рд╡реНрдпреВ рдмрдирд╛рддреЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЕрдиреБрд░реЛрдз рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдмрд╕реЗ рдЖрдо рд╕рдВрдЪрд╛рд▓рди рд╣реИрдВ рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рднреЗрдЬреЗ рдЧрдП рдЕрдиреБрд░реЛрдз рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╣реЛрддреЗ рд╣реИрдВред

  • рд▓реВрдк рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдореЛрдВ рдкрд░ Iterate рдХрд░реЗрдВред
  • ToList, ToArray, Single, Count рдЬреИрд╕реЗ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред
  • рдХреНрд╡реЗрд░реА рд╕реЗ рдбреЗрдЯрд╛ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдПред

рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдИрдПрдл рдХреЛрд░ рдХреЛрдб рдХреЛ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░реЗрдВ?


(1) рдЖрд╡реЗрджрди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдЖрдкрдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдВрдЪ рдХреЛрдб рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЬрдЧрд╣ (рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ) рд╕реЗ рдкреГрдердХ / рдкреГрдердХ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛрдб рдЦреЛрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред

(2) рдЕрдкрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдЕрдиреНрдп рд╣рд┐рд╕реНрд╕реЛрдВ рдЬреИрд╕реЗ рдХрд┐ рдпреВрдЬрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдпрд╛ рдПрдкреАрдЖрдИ рдЬреИрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХреЛрдб рдХреЛ рди рдорд┐рд▓рд╛рдПрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдбреЗрдЯрд╛рдмреЗрд╕ рдПрдХреНрд╕реЗрд╕ рдХреЛрдб рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдиреНрдп рдореБрджреНрджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

SaveChanges рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рдХреИрд╕реЗ рдмрдЪрд╛рдпрд╛ рдЬрд╛рдП ?


рдпрджрд┐ рд╕рдореНрдорд┐рд▓рд┐рдд рд░рд┐рдХреЙрд░реНрдб рд╕рдорд╛рди рд╣реИрдВ, рддреЛ рдпрд╣ рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрд╡ рдСрдкрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред

рдЧрд▓рдд

using(var db = new NorthwindEntities())
{
var transaction = db.Database.BeginTransaction();

try
{
    //   1
    var  obj1 = new Customer();
    obj1.CustomerID = "ABCDE";
    obj1.CompanyName = "Company 1";
    obj1.Country = "USA";
    db.Customers.Add(obj1);

  //          db.SaveChanges();

    //   2
    var  obj2 = new Customer();
    obj2.CustomerID = "PQRST";
    obj2.CompanyName = "Company 2";    
    obj2.Country = "USA";
    db.Customers.Add(obj2);

    //   
    db.SaveChanges();

    transaction.Commit();
}
catch
{
    transaction.Rollback();
}
}

рд╕рд╣реА рдврдВрдЧ рд╕реЗ

using(var db = new NorthwindEntities())
{
var transaction = db.Database.BeginTransaction();

try
{
   //  1
    var  obj1 = new Customer();
    obj1.CustomerID = "ABCDE";
    obj1.CompanyName = "Company 1";
    obj1.Country = "USA";
    db.Customers.Add(obj1); 

    //   2
    var  obj2 = new Customer();
    obj2.CustomerID = "PQRST";
    obj2.CompanyName = "Company 2";    
    obj2.Country = "USA";
    db.Customers.Add(obj2);

   //    N 
    db.SaveChanges();

    transaction.Commit();
}
catch
{
    transaction.Rollback();
}
}

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

//    
public async Task<IActionResult> AddDepositToHousehold(int householdId, DepositRequestModel model)
{
    using (var transaction = await Context.Database.BeginTransactionAsync(IsolationLevel.Snapshot))
    {
        try
        {
            //     
            var deposit = this.Mapper.Map<Deposit>(model);
            await this.Context.Deposits.AddAsync(deposit);

            await this.Context.SaveChangesAsync();

            //    
               var debtsToPay = await this.Context.Debts.Where(d => d.HouseholdId == householdId && !d.IsPaid).OrderBy(d => d.DateMade).ToListAsync();

            debtsToPay.ForEach(d => d.IsPaid = true);

            await this.Context.SaveChangesAsync();

            //   
            var household = this.Context.Households.FirstOrDefaultAsync(h => h.Id == householdId);

            household.Balance += model.DepositAmount;

            await this.Context.SaveChangesAsync();

            transaction.Commit();
            return this.Ok();
        }
        catch
        {
            transaction.Rollback();
            return this.BadRequest();
        }
    }
}

рдЯреНрд░рд┐рдЧрд░, рдХрдореНрдкреНрдпреВрдЯреЗрдб рдлрд╝реАрд▓реНрдб, рдХрд╕реНрдЯрдо рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ EF рдХреЛрд░


EF Core рд╡рд╛рд▓реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдкрд░ рд▓реЛрдб рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕рд░рд▓ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдб рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдЯреНрд░рд┐рдЧрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реЛрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрд╣реБрдд рднреНрд░рдорд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдпреВрдЬрд╝рд░-рдбрд┐рдлрд╝рд╛рдЗрдВрдб рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рднреНрд░реВрдг рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджреМрд░рд╛рди рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ!

рдИрдПрдл рдХреЛрд░ рдореЗрдВ рдХрдВрдЬреНрдпреВрд░реЗрдмрд┐рд▓рд┐рдЯреА


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

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

public async Task<List<Blog>> GetBlogsAsync()
{
    using (var context = new BloggingContext())
    {
        return await context.Blogs.ToListAsync();
    }
}

LINQ рд╕рдВрдХрд▓рд┐рдд рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЖрдк рдХреНрдпрд╛ рдЬрд╛рдирддреЗ рд╣реИрдВ?


рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдРрд╕рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИ рдЬреЛ рдмрд╛рд░-рдмрд╛рд░ рдЗрдХрд╛рдИ рдврд╛рдВрдЪреЗ рдореЗрдВ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд╕рдорд╛рди рдХреНрд╡реЗрд░реА рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЕрдХреНрд╕рд░ рдХреНрд╡реЗрд░реА рдХреЛ рдПрдХ рдмрд╛рд░ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдХреЗ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрдИ рдмрд╛рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЖрд╡реЗрджрди рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╢рд╣рд░ рдореЗрдВ рд╕рднреА рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ; рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рд╢рд╣рд░ рдХреЛ рд░рдирдЯрд╛рдЗрдо рдХреЗ рд░реВрдк рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред LINQ to Entities рдЗрд╕ рдЙрджреНрджреЗрд╢реНрдп рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рд┐рдд рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред

.NET рдлреНрд░реЗрдорд╡рд░реНрдХ 4.5 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, LINQ рдХреНрд╡реЗрд░реАрдЬрд╝ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреИрд╢ рдХреА рдЬрд╛рддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЖрдк рдЕрднреА рднреА рдмрд╛рдж рдХреЗ рд░рдиреЛрдВ рдореЗрдВ рдЗрд╕ рд▓рд╛рдЧрдд рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рд┐рдд LINQ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╕рдВрдХрд▓рд┐рдд рдкреНрд░рд╢реНрди LINQ рдкреНрд░рд╢реНрдиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреИрд╢ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ EnQerable.Contains рдСрдкрд░реЗрдЯрд░ рдХреЛ рдЗрди-рдореЗрдореЛрд░реА рдХрд▓реЗрдХреНрд╢рдВрд╕ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реА Entities рд╕реЗ LINQ рдХреНрд╡реЗрд░реАрдЬрд╝ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреИрд╢ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рдВрдХрд▓рд┐рдд LINQ рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ рдЗрди-рдореЗрдореЛрд░реА рдХрд▓реЗрдХреНрд╢рдВрд╕ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИред

рдХрдИ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ ред

рдмрдбрд╝реЗ DbContext рд╕рдВрджрд░реНрднреЛрдВ рдХреЛ рдордд рдмрдирд╛рдУ!


рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореИрдВ рдЖрдк рдореЗрдВ рд╕реЗ рдХрдИ рдХреЛ рдЬрд╛рдирддрд╛ рд╣реВрдВ, рдпрджрд┐ рд▓рдЧрднрдЧ рд╕рднреА рдирд╣реАрдВ, рдЖрд▓рд╕реА f_u__c_k__e_r__s рдФрд░ рдкреВрд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА, рдЖрдк рдПрдХ рд╕рдВрджрд░реНрдн рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕-рдкреНрд░рдердо рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рдЪ рд╣реИред рдФрд░ рд╡реНрдпрд░реНрде рдореЗрдВ рддреБрдо рдХрд░рддреЗ рд╣реЛ! рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрджрд░реНрдн рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдмреЗрд╢рдХ, рд╕рдВрджрд░реНрднреЛрдВ рдХреЗ рдмреАрдЪ рдХрдиреЗрдХреНрд╢рди рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдпрд╣ рдПрдХ рдЛрдг рд╣реИред рдПрдХ рддрд░реАрдХрд╛ рдпрд╛ рджреВрд╕рд░рд╛, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╕рдВрджрд░реНрдн рдореЗрдВ 50 рд╕реЗ рдЕрдзрд┐рдХ рдЯреЗрдмрд▓ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред

рд╕рдВрджрд░реНрдн рд╕рдореВрд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ (DdContext рдХреЛ рд╕рдорддрд▓ рдХрд░рдирд╛)


DbContext рдкреВрд▓ рдХрд╛ рдЕрд░реНрде рдкреВрд▓ рд╕реЗ DbContext рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдирд╛ рд╣реИ , рдЬрд┐рд╕рд╕реЗ рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдпрд╛ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдмрдирд╛рдиреЗ рд╕реЗ рдмреЗрд╣рддрд░ рдкреНрд░рджрд░реНрд╢рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред ADO.NET рдореЗрдВ рдХрдиреЗрдХреНрд╢рди рдкреВрд▓ рдмрдирд╛рдиреЗ рдХрд╛ рдпрд╣ рднреА рдореБрдЦреНрдп рдХрд╛рд░рдг рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рд▓рд╛рдн рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдХрдиреЗрдХреНрд╢рди рдЖрдорддреМрд░ рдкрд░ рдПрдХ рдХрдард┐рди рд╕рдВрд╕рд╛рдзрди рд╣реЛрддреЗ рд╣реИрдВред

using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace Demos
{
    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
    }

    public class BloggingContext : DbContext
    {
        public static long InstanceCount;

        public BloggingContext(DbContextOptions options)
            : base(options)
            => Interlocked.Increment(ref InstanceCount);

        public DbSet<Blog> Blogs { get; set; }
    }

    public class BlogController
    {
        private readonly BloggingContext _context;

        public BlogController(BloggingContext context) => _context = context;

        public async Task ActionAsync() => await _context.Blogs.FirstAsync();
    }

    public class Startup
    {
        private const string ConnectionString
            = @"Server=(localdb)\mssqllocaldb;Database=Demo.ContextPooling;Integrated Security=True;ConnectRetryCount=0";

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<BloggingContext>(c => c.UseSqlServer(ConnectionString));
        }
    }

    public class Program
    {
        private const int Threads = 32;
        private const int Seconds = 10;

        private static long _requestsProcessed;

        private static async Task Main()
        {
            var serviceCollection = new ServiceCollection();
            new Startup().ConfigureServices(serviceCollection);
            var serviceProvider = serviceCollection.BuildServiceProvider();

            SetupDatabase(serviceProvider);

            var stopwatch = new Stopwatch();

            MonitorResults(TimeSpan.FromSeconds(Seconds), stopwatch);

            await Task.WhenAll(
                Enumerable
                    .Range(0, Threads)
                    .Select(_ => SimulateRequestsAsync(serviceProvider, stopwatch)));
        }

        private static void SetupDatabase(IServiceProvider serviceProvider)
        {
            using (var serviceScope = serviceProvider.CreateScope())
            {
                var context = serviceScope.ServiceProvider.GetService<BloggingContext>();

                if (context.Database.EnsureCreated())
                {
                    context.Blogs.Add(new Blog { Name = "The Dog Blog", Url = "http://sample.com/dogs" });
                    context.Blogs.Add(new Blog { Name = "The Cat Blog", Url = "http://sample.com/cats" });
                    context.SaveChanges();
                }
            }
        }
        private static async Task SimulateRequestsAsync(IServiceProvider serviceProvider, Stopwatch stopwatch)
        {
            while (stopwatch.IsRunning)
            {
                using (var serviceScope = serviceProvider.CreateScope())
                {
                    await new BlogController(serviceScope.ServiceProvider.GetService<BloggingContext>()).ActionAsync();
                }

                Interlocked.Increment(ref _requestsProcessed);
            }
        }

        private static async void MonitorResults(TimeSpan duration, Stopwatch stopwatch)
        {
            var lastInstanceCount = 0L;
            var lastRequestCount = 0L;
            var lastElapsed = TimeSpan.Zero;

            stopwatch.Start();

            while (stopwatch.Elapsed < duration)
            {
                await Task.Delay(TimeSpan.FromSeconds(1));

                var instanceCount = BloggingContext.InstanceCount;
                var requestCount = _requestsProcessed;
                var elapsed = stopwatch.Elapsed;
                var currentElapsed = elapsed - lastElapsed;
                var currentRequests = requestCount - lastRequestCount;

                Console.WriteLine(
                    $"[{DateTime.Now:HH:mm:ss.fff}] "
                    + $"Context creations/second: {instanceCount - lastInstanceCount} | "
                    + $"Requests/second: {Math.Round(currentRequests / currentElapsed.TotalSeconds)}");

                lastInstanceCount = instanceCount;
                lastRequestCount = requestCount;
                lastElapsed = elapsed;
            }

            Console.WriteLine();
            Console.WriteLine($"Total context creations: {BloggingContext.InstanceCount}");
            Console.WriteLine(
                $"Requests per second:     {Math.Round(_requestsProcessed / stopwatch.Elapsed.TotalSeconds)}");

            stopwatch.Stop();
        }

EF рдХреЛрд░ рдореЗрдВ CRUD рдХреЗ рд╕рд╛рде рдЕрдирд╛рд╡рд╢реНрдпрдХ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдХреИрд╕реЗ рдмрдЪреЗрдВ?


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

рдХреНрдпрд╛ рдХрд░реЗрдВ рдЬрдм рдЖрд╡реЗрджрди рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдЪреАрдЬреЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЦрд░рд╛рдм рд╣реИрдВ?


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

рдЖрдк, рджреЛрд╕реНрддреЛрдВ рдФрд░ рд╕рд╣рдХрд░реНрдорд┐рдпреЛрдВ рдХреЛ рдЧрддрд┐ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ!

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


All Articles