Common mistakes in EF Core - Jernej Kavka - NDC Oslo 2023

Sdílet
Vložit
  • čas přidán 25. 06. 2023
  • When JK worked with many different clients and projects, he frequently heard "EF Core is slow" or "We should do this in raw SQL" only to realize they haven't used EF Core correctly.
    JK will show you how to improve your EF Core statements as well as how various configurations impacts the performance and scalability of your application. You'll be blown away at how small changes can significantly impact not only the performance but also stability of the application.
    Check out our new channel:
    NDC Clips:
    ‪@ndcclips‬
    Check out more of our featured speakers and talks at
    ndcconferences.com/
    ndcoslo.com/
  • Věda a technologie

Komentáře • 55

  • @mekowgli
    @mekowgli Před 4 měsíci +5

    I think the main issue are developers who have no idea or don't care about what they are doing / how stuff works under the hood. They threat everything as a black box API (including all libraries, services and the computer itself). All that matters is closing a ticket. That's why I believe a formal education, that gives you a shallow but broad understanding of all the layers (electronics, CPU's, assembler, compilers, operating systems, .. , databases, networks, cloud, ...) is extremely important. It prevents you from pulling 10M records into memory to do a count.

  • @KREKER8331
    @KREKER8331 Před 3 měsíci +2

    Wow,Amazing Talking! I learned a lot , thank you!

  • @vivekkaushik9508
    @vivekkaushik9508 Před 11 měsíci +11

    Excellent talk. I learned so much in only 30 mins.

  • @momusic1427
    @momusic1427 Před 3 měsíci +2

    Learned a lot from this . thanks man

  • @oddikaro8236
    @oddikaro8236 Před 6 měsíci +3

    Great talk!!

  • @fabienWendpanga
    @fabienWendpanga Před 11 měsíci +9

    Excellent Talk! Always learning something with all those NDC talks. I am going to be looking at Dapper twice before using it instead of EF

  • @victordam3921
    @victordam3921 Před 6 měsíci +2

    Amazing Talking althouth I had woked with EF for many year but your experience still valuable for me I know almost issue you talk but your bonus is pretty useful , appreciate 30 mins

  • @pagnew9649
    @pagnew9649 Před 6 měsíci +4

    You are an EF Core expert and clean code developer.
    DbContext:

  • @rezendemarcio
    @rezendemarcio Před 11 měsíci +4

    Very good talk. Learned a lot!
    Thanks!!

  • @duongtrunghs2925
    @duongtrunghs2925 Před 6 měsíci +2

    great, I learned a lot, thank you so much.

  • @eddypartey1075
    @eddypartey1075 Před 8 měsíci +2

    51:56 It also didn't add cancellation token
    Brilliant talk btw I've learned a lot from it. Simple and straight to the point. Thank you!

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci +1

      Yes, I missed that first time, but now I love that it's in there, so I can tell everyone, "Always review the code generated by the AI. You can see, it's not using CancellationToken". 😊
      I also didn't add CancellationToken, AsNoTracking and TagWith on all of the examples, mainly to not distract people from the point I'm trying to make.

  • @DhavalChandnani341
    @DhavalChandnani341 Před měsícem

    Very helpful

  • @maxiphobos
    @maxiphobos Před 5 měsíci +1

    Thanks a lot!

  • @jorgellanque7704
    @jorgellanque7704 Před 6 měsíci +2

    thansks a lot, I've took down a lot

  •  Před 11 měsíci +2

    Nice talk.

  • @vivekkaushik9508
    @vivekkaushik9508 Před 11 měsíci +20

    Its werid how it sounds so natural at 1.75x.

  • @tore28
    @tore28 Před 11 měsíci +8

    SQL Server implements AsNoTracking in a way that reduces the needs for table locks and does a DB snapshot (ReadCommitted I guess as isolation level ) that gives benefit. Most developers use SQL Server

  • @viacheslavp
    @viacheslavp Před 2 měsíci

    Enabling DbContext pooling doesn't affect DB connection pooling, which is enabled by default

  • @andrewshirley9240
    @andrewshirley9240 Před 6 měsíci +1

    I was kinda skipping around so maybe I missed exactly what he was saying, but around 22:00 he's saying "do a direct projection into a container object with a Select statement instead of using .Include, because Include will cause a join and joins are bad!" The "because" half of that sentence is 100% wrong. It will still cause the SQL generated to join, and joins aren't bad because they're the entire freakin' point of a relational database, if you want to make your life hell you can go NoSQL and design around never joining, but I'll keep my relational data, thanks. The value of Select projections is that when you do that, it only queries the columns referenced by the final projection into the object. If you do DbSet.ToList() or DbSet.Include(x => x.OtherSet), then it queries *all columns* by default, so if you have 20 columns and only need 2 of 'em, that's a load of data you're sending over the wire for no reason. That's what makes it bad, not the joins.

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci +2

      You are correct and that's the point I wanted to make at 20:50. 😊
      The point was that if you use .Select instead, you'll implicitly join tables rather than explicitly. This means that if you no longer map a property that needs a join, it will be removed for you. In case of explicit joins, they will be added whether you need them or not. It's about embracing relational databases without needing to micromanage joins. 😊
      I've seen many cases where developers forget to remove or they even spam a lot of `.Include()` when they are not really needed, causing unnecessarily complex queries with no benefits.

  • @BryonLape
    @BryonLape Před 9 měsíci +1

    Skip to 10:00 to start to get to the point.

  • @manmohanmundhraa3087
    @manmohanmundhraa3087 Před 5 měsíci

    Sir, Which one will be better in terms of performance ? ExecuteUpdate or execting update statement directly using EF Core.

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 5 měsíci

      Usually ExecuteUpdate. But if the number of properties changed can range from 0 to lots, SaveChanges might be better as it won't do anything if nothing changed. (you don't have to track everything manually)

  • @HikingUtah
    @HikingUtah Před 7 měsíci +1

    Gets around to the topic at 9:59.

  • @programmerako
    @programmerako Před 11 měsíci

    does it need AsNoTracking when using select expression?

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci

      Yes and no., as long you don't use the entire property entity like for example `.Select(x => new { Author = x.Author })`. In this case, `Author` property is still tracked (at least in EF Core 6) as you're taking the entire entity instead of its properties.
      Adding explicit AsNoTracking() prevents tracking in cases like these. It's not a common issue, and usually, I always map into a DTO or model that makes it impossible for the query to be mapped.

  • @tore28
    @tore28 Před 11 měsíci +1

    ExecuteUpdate is introduced in .NET 7 ?

    • @hexorf
      @hexorf Před 11 měsíci +1

      Yes, it was introduced in EF Core 7.

  • @SteveNgaiCheeWeng
    @SteveNgaiCheeWeng Před 11 měsíci +3

    What are the differences between AddDbContextFactory vs AddDbContextPool in terms of performance?

    • @hexorf
      @hexorf Před 11 měsíci +4

      Hi Steve, AddDbContextFactory is to better control the lifetime of the DbContext while DbContextPool keeps them alive and recycles them on demand.
      For instance, you want to use DbContextFactory for Blazor or console application to get a fresh instance where you only might have 1 DI scope. You could implement you own pool within the factory to recycle DbContext but that's not done for you. By default, DbContext is always fresh.
      DbContextPool recycles DbContext which means that requesting "new" DbContext is much cheaper, allowing you to scale better, for almost for free. As long you don't have any stateful fields or properties, you should be fine. Injecting service or interceptors in constructor can cause DbContext to become stateful (service/interceptor stays alive longer then it should and used in the wrong DI scope), so be careful with that. Injecting a service like date provider should be fine.

    • @andreiguzovski7774
      @andreiguzovski7774 Před 11 měsíci +2

      @@hexorf Isn't DbContext designed as light-weight short-lived object which should live only during one operation and then be disposed?

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci

      @@andreiguzovski7774 correct but in cases of console, desktop, background jobs, mobile and Blazor application, you are responsible for the lifetime of the DbContext. This is why DbContextFactory can be essential to your application. DbContextFactory can also be used when you want to execute things on DB in parallel, since DbContext isn't thread safe.

  • @vasiliigodunov1746
    @vasiliigodunov1746 Před 11 měsíci +2

    Calculate how long it will take to cancel a request with a write transaction. This may surprise.

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci

      I might consider a test for this. Considering it might need to revert the changes, I can imagine it will take longer. If an operation should happen once you get to certain point of application, you can use `CancellationToken.None`. This gives you an added bonus of letting other devs know, ignoring cancellation is a deliberate behavior.

  • @nkazimulojudgement3583
    @nkazimulojudgement3583 Před 11 měsíci

    wait? isn't EF core executing from server side by default?

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci +1

      Not if you cast to IEnumerable too quickly. Also... GroupBy technically can run on client side as well and a few other operations. I'm working on a talk for NDC Sydney to show that. For a teaser, `GroupBy(x => x.Country)` usually gets converted into `SELECT ... FROM Authors ORDER BY Country` and it gets converted into C# group on client-side. (works since EF Core 3.1)
      But... If you make this `.GroupBy(x => x.Country).Select(x => new { x.Country, NumOfAuthors = x.Count() }` this actually can convert into `SELECT Country, COUNT(*) as 'NumOfAuthors' GROUP BY Country`. The talk is work in progress but I'm testing the boundaries of EF Core LINQ and how it gets converted into SQL LINQ.

  • @geertdoornbos
    @geertdoornbos Před 11 měsíci +5

    Dapr is not Dapper !

    • @kingfriday4
      @kingfriday4 Před 6 měsíci +1

      Yep, major icon mistake there :)

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 Před 6 měsíci

      @geertdoornbos and @franzhemmer6608, fixed for NDC Porto. :)
      Thank you for noticing!

  • @monsieurouxx
    @monsieurouxx Před 11 měsíci +5

    Cool story, brah. Now why don't you go ahead and MAKE IT CLEAR IN THE GOD DAMN DOCUMENTATION? I'm a senior Dev who's been using EF core on and off going on 10 years, and no one, I mean literally no one, human or automated tool, has ever questioned my code -- which was riddled with those "obvious mistakes"

    • @nkazimulojudgement3583
      @nkazimulojudgement3583 Před 11 měsíci

      isnt EF core excuting from Server side by default

    • @monsieurouxx
      @monsieurouxx Před 11 měsíci +1

      @@nkazimulojudgement3583 how is that connected to what I wrote?

    • @meJevin
      @meJevin Před 10 měsíci

      Probably because the projects you were working on are small enough to let you use EF poorly

    • @meJevin
      @meJevin Před 10 měsíci +2

      The examples given in this presentation are something a person who can’t tell the difference between an IEnumerable and IQueryable would make. If your code has been “riddled with those obvious mistakes” then I have a really hard time understanding why you have the audacity to call yourself anything other that a jr dev my man 😂

    • @meJevin
      @meJevin Před 10 měsíci

      Are you by any chance Indian

  • @14bebop14
    @14bebop14 Před 11 měsíci

    stink in the linq