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

Поділитися
Вставка
  • Опубліковано 25 чер 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/
  • Наука та технологія

КОМЕНТАРІ • 55

  • @mekowgli
    @mekowgli 3 місяці тому +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 3 місяці тому +2

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

  • @momusic1427
    @momusic1427 2 місяці тому +2

    Learned a lot from this . thanks man

  • @oddikaro8236
    @oddikaro8236 6 місяців тому +3

    Great talk!!

  • @pagnew9649
    @pagnew9649 6 місяців тому +4

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

  • @vivekkaushik9508
    @vivekkaushik9508 11 місяців тому +11

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

  • @DhavalChandnani341
    @DhavalChandnani341 Місяць тому

    Very helpful

  • @victordam3921
    @victordam3921 6 місяців тому +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

  • @fabienWendpanga
    @fabienWendpanga 11 місяців тому +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

  • @duongtrunghs2925
    @duongtrunghs2925 6 місяців тому +2

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

  • @eddypartey1075
    @eddypartey1075 8 місяців тому +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 5 місяців тому +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.

  • @rezendemarcio
    @rezendemarcio 11 місяців тому +4

    Very good talk. Learned a lot!
    Thanks!!

  • @maxiphobos
    @maxiphobos 4 місяці тому +1

    Thanks a lot!

  • @jorgellanque7704
    @jorgellanque7704 6 місяців тому +2

    thansks a lot, I've took down a lot

  •  11 місяців тому +2

    Nice talk.

  • @tore28
    @tore28 11 місяців тому +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 2 місяці тому

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

  • @vivekkaushik9508
    @vivekkaushik9508 11 місяців тому +20

    Its werid how it sounds so natural at 1.75x.

  • @andrewshirley9240
    @andrewshirley9240 6 місяців тому +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 5 місяців тому +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.

  • @manmohanmundhraa3087
    @manmohanmundhraa3087 5 місяців тому

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

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 4 місяці тому

      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)

  • @programmerako
    @programmerako 10 місяців тому

    does it need AsNoTracking when using select expression?

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 5 місяців тому

      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.

  • @HikingUtah
    @HikingUtah 7 місяців тому +1

    Gets around to the topic at 9:59.

  • @BryonLape
    @BryonLape 8 місяців тому +1

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

  • @tore28
    @tore28 11 місяців тому +1

    ExecuteUpdate is introduced in .NET 7 ?

    • @hexorf
      @hexorf 11 місяців тому +1

      Yes, it was introduced in EF Core 7.

  • @SteveNgaiCheeWeng
    @SteveNgaiCheeWeng 11 місяців тому +3

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

    • @hexorf
      @hexorf 11 місяців тому +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 11 місяців тому +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 5 місяців тому

      @@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 11 місяців тому +2

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

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 5 місяців тому

      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 10 місяців тому

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

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 5 місяців тому +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 11 місяців тому +5

    Dapr is not Dapper !

    • @kingfriday4
      @kingfriday4 6 місяців тому +1

      Yep, major icon mistake there :)

    • @jernejkavkajkssw6662
      @jernejkavkajkssw6662 5 місяців тому

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

  • @14bebop14
    @14bebop14 11 місяців тому

    stink in the linq

  • @monsieurouxx
    @monsieurouxx 11 місяців тому +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 10 місяців тому

      isnt EF core excuting from Server side by default

    • @monsieurouxx
      @monsieurouxx 10 місяців тому +1

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

    • @meJevin
      @meJevin 9 місяців тому

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

    • @meJevin
      @meJevin 9 місяців тому +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 9 місяців тому

      Are you by any chance Indian