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.
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
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.
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
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.
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.
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)
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.
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 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.
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.
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.
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"
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 😂
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.
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
Wow,Amazing Talking! I learned a lot , thank you!
You are an EF Core expert and clean code developer.
DbContext:
Thank you for writing this into the comments. :)
Excellent talk. I learned so much in only 30 mins.
Great talk!!
Learned a lot from this . thanks man
This is so insightful. Learned a lot from this single video. Thanks for sharing
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
great, I learned a lot, thank you so much.
Very good talk. Learned a lot!
Thanks!!
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!
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.
Thanks a lot!
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
Its werid how it sounds so natural at 1.75x.
Wow
Enabling DbContext pooling doesn't affect DB connection pooling, which is enabled by default
thansks a lot, I've took down a lot
Nice talk.
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.
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.
Very helpful
Insightful
Sir, Which one will be better in terms of performance ? ExecuteUpdate or execting update statement directly using EF Core.
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)
Gets around to the topic at 9:59.
Skip to 10:00 to start to get to the point.
Calculate how long it will take to cancel a request with a write transaction. This may surprise.
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.
ExecuteUpdate is introduced in .NET 7 ?
Yes, it was introduced in EF Core 7.
What are the differences between AddDbContextFactory vs AddDbContextPool in terms of performance?
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.
@@hexorf Isn't DbContext designed as light-weight short-lived object which should live only during one operation and then be disposed?
@@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.
does it need AsNoTracking when using select expression?
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.
Dapr is not Dapper !
Yep, major icon mistake there :)
@geertdoornbos and @franzhemmer6608, fixed for NDC Porto. :)
Thank you for noticing!
wait? isn't EF core executing from server side by default?
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.
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"
isnt EF core excuting from Server side by default
@@nkazimulojudgement3583 how is that connected to what I wrote?
Probably because the projects you were working on are small enough to let you use EF poorly
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 😂
Are you by any chance Indian
stink in the linq