@@dave7244 Then a lot less people would click. I'm sorry that's how the algo (psychology) works 🤷♂ I need to battle with getting view & providing information at the same time.
@@MilanJovanovicTechgot me excited, but didn't take long to realize the answer is no for me. For me dapper is optimal for performance and control. I created a wrapper that handles connections and turns most common use case of getting a collection or executing a command to a single line function.
I would have solved this case with Dapper by executing 2 selects using the QueryMultiple method. It would have still been one roundtrip, and there would be no need to add unnecessary complexity to separate the result data...
It's one round trip on SQL Server since it has MARS. It won't work the same on PostgreSQL, for example. And the mapping can be solved with an extension method + mapping function.
@@MilanJovanovicTech To clarify his comment: In your video, your query returns 1 result set with 4 columns, with the value in the first 2 columns being duplicated for every LineItem returned. Peter is saying he would instead write a query with two select statements. So from the database he would receive 2 result sets - the first has 1 row with 2 columns - the orderId and customerId. The second result set has 2 columns - the lineItemId and the lineItemPrice. This removes the duplication of orderId and customerId that you had in your example. To return an Order object with its LineItems, you just assign the list of LineItems from the 2nd result set to the LineItems variable of the Order class - this is what he meant with removing complexity of separating the data. As per his comment, writing one sql string containing both selects is still only making one trip to the database. This is the way I'd do it with Dapper as well. If you were selecting multiple orders as well as their lineitems, and want to return a list of orders, it gets a little trickier. In that case, I'd still do it the same way as in Peter's comment - first create the list of orders from the first result set, but then to assign the LineItems to each order, I'd loop through the Orders 1 time to create a dictionary of Orders, then loop through the LineItems and use the orders dictionary to add each LineItem to the appropriate Order's LineItems list.
@@reikooters I understood that perfectly well 😅 I know how JOINs work... And I said that's only possible - fetch everything in one round trip - on SQL Server, and not other SQL providers.
@@MilanJovanovicTech Ok now that I re-read your comment that makes sense. When you said MARS it threw me off as Multiple Active Result Sets is a setting that allows one connection to the SQL server to be used for serving multiple requests at once, which is a bit different topic. But I understand now that what you meant was that other databases can't return multiple result sets in a single batch like described earlier. Sorry for the confusion.
This inline sql is a way to create unmaintainable code. Just like stored procedures. If you have lots of this and you want to change your database schema your build works but everything breaks when you run it. the strength of EF is that all code is typed, no magic strings, so changing an enitity class will break all using code during local development. Reducing bugs by a lot.
@@MilanJovanovicTech Who has the budget to have 100% code coverage? it is much better to fail in the build or before you even try to build, you ll have the errors in the ide. Choosing reliable ways to code stuff saves you from a lot of unneeded bugs. Inline SQL (and stored procedures or magic strings (use nameof() instead of the "name"!) has been one of the biggest problems in code maintainability and reliability that i have encountered. I strongly advise against using it, its bad practice in my "book".
it can be more managable with using nameof's instead of typing them as strings but still writing raw sql is terrible idea imho, also this is very low code, i don't like to have my objects have id's at all. just have actual objects that those id's point to.
@@MilanJovanovicTech I hope it will have an edge. I became so comfortable with Dapper, that I do not to rewrite things. But if EF will be faster just fo microsecond, than I will not sleep :-)
It would be useful to give a brief explanation of the use case you are implementing beforehand. Some of us struggle to follow if we don’t know where you are heading.
working with childs was, is and will always be a problem. Dapper comes with the "splitOn" solution where you have to define at which column you want to split. After that you have to add the childs in a separate dictionary. RepoDB define for itself to not handle childs. Now this EF 8 Solution is to be honest also cluncy. You have to define a flat-object to group it after that. It may be not the fastest soulution but EF with just saying .Include(...) gives by far the best readable solution for developers. Saving childs is by the way possible by define user-defined-types for SQL Server and pass the whole child as parameter. And EF provide also a great solution.
It's not a solution, just something I came up with quickly. I'm sure there are better solutions
Рік тому+4
Dapper can do map one to many relations.. you don't need to create the joined line record, and still, dapper needs no initialization like EF does with dbcontext generation, so in serverless functions (aws lambda or azure functions) it still gives you a big edge...
Hi Milan, really appreciate the time and effort you put into this stuff. I really wish there would be more content on some of the other tools out there.
I'm a bit iffy about this. I consider hardcoded string queries a code smell in my projects. I would rather lose a couple of nanoseconds of performance than have hardcoded queries.
We do have huge databases (>1TB), having projections of specific data is crucial for the microservices that interact with these databases. Not everything can be an entity, and you certainly some times want something more custom. While i understand why you would want a typed query, sometimes you gotta go raw.
Sometimes the query compiles by EF Core is really slow, and we need to make it right by SQL query instead. Some features in my current project have this problem so if someone new to EF Core, please keep in mind it is really great that ORM can do so much things for us, but sometimes SQL query is not that bad
@@MilanJovanovicTech that's not the problem i mainly have. The problem for me is that it's hard coded and if, for some reason, someone changes the names of the properties, you have to manually change the occurrences by hand ✋
@@MilanJovanovicTech This is the work of a DBA not a developer. SQL is more complex than people think, there's a lot of things to think to get a better performance in SQL.. there's also tools in SQL to track performance and schema of a request. And of course you can export a Schema File .SQL and you put that in Git to track changes. Actually it's a simple request you do, but imagine when you work for a big company who have some requests of thousands of line.. it's better and safe and readable to put that in Stored procedures. In my opinion there's two ways. Use code first like EF or use Dapper or EF with stored procedures. Remember that as a Developer you should never assume risques of a DBA. Because you are not paid for, and you can be in a trouble if something is wrong in production. Also, every developer should learn SQL server, no one can be a good developer without that. But remember to let everyone assume his job. Because he knows How to do it in a good way.
That defeats the purpose of the ORM... With an ORM like EF you get platform independance, which means if you decide to migrate to a different DBMS, all you need to do is switch DB provider and connection string. If you write your application with a bunch of stored procs, you have to rewrite them. I work on ERP data systems with hundreds of tables and millions of records, the only stored procs or db triggers we use are for very specific things, like audit tasks, access control or user rights management, maintenance tasks, etc... Things that would be too complicated to do purely in EF, basically.
Very interesting, thank u! If we are getting nit-picky, there is the overhead of provisioning a dbcontext instance from the db pool every time you need to run a query. Whereas using dapper I would presume it wouldn't rely on as much resources, tho am only speculating here. Will look forward to seeing your benchmarks video!
An awesome video, an awesome feature and awesome explanations! I've worked with Dapper for 2 years so it looks so intresting. You also can group data via sql script and miss linq grouping and selecting data
Wow, that can truly put the need of the Dapper back. Also in this video a nice comparison of 2 libs can be seen and how much easier to query data using high level EfCore features and you get the model you need straight away
My problem with this approach in general is that you are returning a lot of duplicated data. In you example you are only returning a few fields from the order but what if you need more? Every field you add is duplicated for each line item. 1000 line items means you just transferred and loaded 1000 duplicate fields that are going to discard.
@@MilanJovanovicTech why not put the group by and aggregates in the SqlQuery ? so they are done at the db server side and save the network traffic volume at the cost of server CPU consumption.
@@joeng3385 You do not want an aggregate of the rows, you want all the rows so either you would need to run two queries, which adds overhead, or you do as the example in the video. I do not know if EF_Core can use multiple results, but that would be a lot more complex query on the SQL side so unless its a lot of data from the order its probably not worth it. And if it really is, then you probably want to make it into two separate queries and merge in C# instead
Writing short subtitles in the video seems a bit redundant when UA-cam can already do it automatically. Why not write the custom subtitles there? Personally I find the in-video too-quick subtitles distracting.
Man this is the video I tell you. Looking forward to seeing what the benchmarks reveal especially now as my team will be doing a rewrite of one of our projects and we are still debating on whether to go EF Core or Dapper or both. 👀
Underwhelming, to say the least. Nick just did a benchmark video, and it's slower than Dapper and pretty much on par with EF LINQ. I'll do another benchmark video in a few months, if I see some improvements are made to this feature.
If you're making a performance video, please also include linq2db with the different ways of writing the queries and optimizing it. At least that would be very interesting for me as I have used it in some projects, and like the abstraction level they have chosen (in between standard EFCore and Dapper).
+1. However I found linq2db creating queries which results were incorrect. However I use it for some features (window functions support, custom aggregate functions support, some patterns that efcore can't handle etc)
If/when you do the comparison between EFCore 8 and Dapper. Can you include both the 'normal' linq approach vs the new raw SQL version in EF 8. I'd be interested in not only the time difference between EF and Dapper. I'm also very interested in understanding the different in times between the two EF approaches (both using EF 8 for a fare comparison).. and keep up the good work mate. I ask as if the performance isn't 'worth' the extra code and hands off SQL vs LINQ approach.. readable and compile safe is my preferred option. I do agree that projection and other approaches to reduce the effort to produce results, at scale. The extra $$ to gain from unreadable code maybe not worth it. Except when it is 'worth' it. Nice work!
+1 for mentioning linq2db i use it to handle bulk scenarios where we have to push tonnes of data rows around or when some special queries ef cannot handle like projected unions.
I really wish we could use EF Core but as far as I know, it does not support the database my company is stuck using - IBM for i or DB2 iSeries (or whatever it’s called these days). To make it worse we are stuck on version v5r4! 😢 Does anybody know if EF Core can be used for this as I haven’t been able to find anything for years.
I switched from EF to Linq2DB and never looked back. Can you compare the two with regards to ease of use, features and performance for some complicated queries? I am interested in your opinion.
Linq2SQL is fine if all you are doing is ad-hoc queries, but EF gives you atomic operations, proper complex type support, database generation from the model, loose coupling through dependency injection, etc...
Even if they're close, I'd probably still keep using Dapper. However, if they can get EF to use source generators rather than reflection, that would change the conversation.
Would that mean that we finally can get dynamic queries (for example dynamic sorting) out of the box, without writing custom expressions or referencing 3rd party packages? Can I combine "classic" lambda-style LINQ queries and have dynamic orderby with this?
EF Core's new feature may make it easier for developers to write raw SQL queries and map the results to objects, which was previously a strength of Dapper. However, this feature does not replace Dapper entirely.
Great video Milan. I'm planning an app and I was thinking about using Dapper for reads and EF Core for writes. If this new feature in EF 8 has the same performance as Dapper I will consider it in the future.
Its more verbose, includes table Details, has a Bug (no items returned throws) and most likely isnt faster. Not sure it's worth the cost of loosing the Advantage of using EF Core even for Performance critical paths. Benchmarks is the first thing we should have done 😅
On the other hand, an order without any items sounds like broken data to begin with :) But this is an example, probably not production level SQL code or mapping.
Nick Chapsas made a video about this feature and he did benchmark it. TLDR: Dapper is still faster and uses less memory. Going back to his earlier videos where he did compare dapper vs regular EF, raw sql in EF looks not that different from regular linq queries. At least for now.
A bit late, but I like Insight.Database library a lot due to its excellent and complex object mapping features. In this example, with InsightDatabase there would be no grouping necessary.
Hi Milan, is there a way that we can constraint the IApplicationDbContext only for AggregateRoots? Because i like using this feature instead of repositories but i want to constraint that only the ARS can access the iappdbcontext
This is what I was going to say. I don't understand why they removed this feature in the first place. Before 8, EF Core made us add the unmapped entity as a dbset, which seems silly. I am glad they're putting it back, though; I have a project that needs to be moved to .NET Core, and this solves one of the major problems.
Hello Milan! interesting video, I am currently using Dapper and SqlKata and extending some methods for SqlKata to be able to use them with my entities without having to write the raw query, for example: var result = _repoQuery.GetQuery() .SelectRaw(columnNames) .Where(nameof(TemplateType.ClassId), classId); I hope to be able to do something similar with this new feature. Thanks for your content!
It is parameterized 😅 It "looks" like an interpolated string, but the argument is actually converted into a SQL parameter. That's how the FromSqlRaw methods work.
Well it does not look like dapper replacement. What if you need to get more than 1 dataset from db, you would join all them to 1 result dataset? Also what if you need to put as a parameter user defined data type? What if you need to get back dataset plus return value from stored procedure? I moved to dapper about 8 years ago, and do not see alternatives for it at least on my project. I mean ef even not close to all dapper functionality.
@@MilanJovanovicTech How is it it parameterised, you just used string interpolation to inject the string into the SQL string. that is not parameterised.
I have a process such as adding 100 thousand records to my MsSql database at once, using an entity framework with a loop. This works successfully at low numbers, but is there any timelout in such large numbers? How can I make this happen in a healthy way?
I was interested in the new feature of EF, but do you REALLY believe Dapper will be displaced so easily? If so, you are incredibly naive. No like or subscribe here. Perhaps if you drop the click bait, and have a performance comparison. But “probably” won’t begin to sway others. And the feature is far from those I use regularly in Dapper.
Hello milan thanks for you efforts, one of the best content creator in my opinion i have a question let's say that in the same app i want to add the categoriesto the product then, as in the diagram you provided serveral videos ago what should it be defined as an aggregate root or it's an entity and if it's an entity how can i add the management endpoints to it like add delete and so on because it will belong to some aggregate root, on the other hand if it was an aggregate root i tried to add a list of it's ids to the product aggregate but couldn't figure out how to configure it with ef can you make a video about simillar scenarios or something like that thanks again ♥
The problem is you're thinking about it from a CRUD perspective. A Category is most likely a standalone entity in your domain. Products can belong to one or more categories. So just configure a one-to-many relationship on the Product side.
Slapper is a cool library that can do that grouping of child records based on ID and return a complex type that pairs very well with Dapper. You just get a list of dynamics from Dapper and feed it to Slapper and if your fields are named right (or you can manually teach it a mapping) it will handle the mapping for you. Works great if you change your types, no need to refactor the mapping code. If EF Core 8 supports reading results from the DB into dynamic it should pair just as well. Overall, if you prefer the Dapper approach I don't see this as a reason to stop using Dapper. It's just copying Dapper and letting that functionality exist alongside traditional EF. If you don't like EF to begin with (like me) - why not just keep using Dapper?
Why do you need EF Core to write pure SQL? The power of EF Core is to write strongly typed queries and to detect errors in a query at the compile time.
There is no reason to use dapper now, 2 weeks ago I was wondering about it, how was possible I cannot to make a raw query without to specify an entity dataset. The Microsoft God listened my thoughts .
Its nice to have but i dont see that replacing dapper... No dapper project ever broke on an upgrade, cant say the same for the ef projects - especially with posgres this was a nightmare for some projects.
@@MilanJovanovicTech what I mean is that "EF Core Feature Be The End Of Dapper" is not a good title. They are all tools, is similar to saying that because you now have philips screwdrivers you don´t need plain screwdrivers.
@@AlfredoPinto Did I say that? No. So, why place words in my mouth? Weak argument... Any speed improvements these ORMs can make will be on the processing side, which is pretty non-impactful. The majority of a query costs will be the network roundtrip time and the work done in the DB.
@@MilanJovanovicTech yes, you are right, you don't say that. But is not about how fast or slow the queries are executed compared to EF and Dapper that makes RepoDB an excellent ORM. What I am saying is that you judge it and discard it without know it, so I got the impression that you do that was just because it wasn't a popular ORM.
@@AlfredoPinto I researched it a bit in the past, but never ended up using it on a real project. I remember it had some feature limitations. Will check if that's been fixed now.
@@MilanJovanovicTech Correct. I'm still using EF 6 (work hates upgrading). so yea, still new to me. I'm really surprised that this is actually parametised. It just looks so wrong compared to what we do.
Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt
what about the performance matrix between the two framework?
Betteridge's law of headlines. "If a headline asks a question then the answer is almost always no".
That's an interesting law, never heard of it before! 😁
Although I believe this feature can solve most Dapper use cases in practice.
I always think the answer is always “maybe but probably not”
The point I am making is that it would be better to tell us what the new feature is rather than click bait headline
@@dave7244 Then a lot less people would click. I'm sorry that's how the algo (psychology) works 🤷♂
I need to battle with getting view & providing information at the same time.
@@MilanJovanovicTechgot me excited, but didn't take long to realize the answer is no for me. For me dapper is optimal for performance and control. I created a wrapper that handles connections and turns most common use case of getting a collection or executing a command to a single line function.
I would have solved this case with Dapper by executing 2 selects using the QueryMultiple method.
It would have still been one roundtrip, and there would be no need to add unnecessary complexity to separate the result data...
It's one round trip on SQL Server since it has MARS. It won't work the same on PostgreSQL, for example. And the mapping can be solved with an extension method + mapping function.
@@MilanJovanovicTech To clarify his comment: In your video, your query returns 1 result set with 4 columns, with the value in the first 2 columns being duplicated for every LineItem returned. Peter is saying he would instead write a query with two select statements. So from the database he would receive 2 result sets - the first has 1 row with 2 columns - the orderId and customerId. The second result set has 2 columns - the lineItemId and the lineItemPrice. This removes the duplication of orderId and customerId that you had in your example. To return an Order object with its LineItems, you just assign the list of LineItems from the 2nd result set to the LineItems variable of the Order class - this is what he meant with removing complexity of separating the data. As per his comment, writing one sql string containing both selects is still only making one trip to the database. This is the way I'd do it with Dapper as well.
If you were selecting multiple orders as well as their lineitems, and want to return a list of orders, it gets a little trickier. In that case, I'd still do it the same way as in Peter's comment - first create the list of orders from the first result set, but then to assign the LineItems to each order, I'd loop through the Orders 1 time to create a dictionary of Orders, then loop through the LineItems and use the orders dictionary to add each LineItem to the appropriate Order's LineItems list.
@@reikooters I understood that perfectly well 😅 I know how JOINs work...
And I said that's only possible - fetch everything in one round trip - on SQL Server, and not other SQL providers.
@@MilanJovanovicTech Ok now that I re-read your comment that makes sense. When you said MARS it threw me off as Multiple Active Result Sets is a setting that allows one connection to the SQL server to be used for serving multiple requests at once, which is a bit different topic. But I understand now that what you meant was that other databases can't return multiple result sets in a single batch like described earlier. Sorry for the confusion.
This inline sql is a way to create unmaintainable code. Just like stored procedures. If you have lots of this and you want to change your database schema your build works but everything breaks when you run it. the strength of EF is that all code is typed, no magic strings, so changing an enitity class will break all using code during local development. Reducing bugs by a lot.
You build works, but your tests should definitely fail
@@MilanJovanovicTech Who has the budget to have 100% code coverage? it is much better to fail in the build or before you even try to build, you ll have the errors in the ide. Choosing reliable ways to code stuff saves you from a lot of unneeded bugs. Inline SQL (and stored procedures or magic strings (use nameof() instead of the "name"!) has been one of the biggest problems in code maintainability and reliability that i have encountered. I strongly advise against using it, its bad practice in my "book".
it can be more managable with using nameof's instead of typing them as strings but still writing raw sql is terrible idea imho, also this is very low code, i don't like to have my objects have id's at all. just have actual objects that those id's point to.
Finally we have both approaches united under one library 🎉 Waiting for performance benchmarks 😉
Thanks for the content! 😃
I'm not sure what to expect. Dapper may still have an edge though. We'll see 😁
@@MilanJovanovicTech I hope it will have an edge. I became so comfortable with Dapper, that I do not to rewrite things. But if EF will be faster just fo microsecond, than I will not sleep :-)
It would be useful to give a brief explanation of the use case you are implementing beforehand. Some of us struggle to follow if we don’t know where you are heading.
Didn't I say at the start what feature I'm building? 🤔
Your channel is a blessing to all .Net developers! All power to you reaching 50k subs and beyond 💯
Thanks a ton!
working with childs was, is and will always be a problem.
Dapper comes with the "splitOn" solution where you have to define at which column you want to split. After that you have to add the childs in a separate dictionary.
RepoDB define for itself to not handle childs.
Now this EF 8 Solution is to be honest also cluncy. You have to define a flat-object to group it after that.
It may be not the fastest soulution but EF with just saying .Include(...) gives by far the best readable solution for developers.
Saving childs is by the way possible by define user-defined-types for SQL Server and pass the whole child as parameter. And EF provide also a great solution.
It's not a solution, just something I came up with quickly. I'm sure there are better solutions
Dapper can do map one to many relations.. you don't need to create the joined line record, and still, dapper needs no initialization like EF does with dbcontext generation, so in serverless functions (aws lambda or azure functions) it still gives you a big edge...
But in the scenario where you're already using EF, this does solve many scenarios.
@@MilanJovanovicTech agreed on that
Hi Milan, really appreciate the time and effort you put into this stuff. I really wish there would be more content on some of the other tools out there.
Which tools in particular?
@@MilanJovanovicTech I like DBConnector and SQL+ is very interesting
I'm a bit iffy about this. I consider hardcoded string queries a code smell in my projects. I would rather lose a couple of nanoseconds of performance than have hardcoded queries.
Im a beginner and just asked my self the same question. This was one of the first statements the Database teacher told us NOT to DO?
We do have huge databases (>1TB), having projections of specific data is crucial for the microservices that interact with these databases. Not everything can be an entity, and you certainly some times want something more custom. While i understand why you would want a typed query, sometimes you gotta go raw.
Sometimes the query compiles by EF Core is really slow, and we need to make it right by SQL query instead. Some features in my current project have this problem so if someone new to EF Core, please keep in mind it is really great that ORM can do so much things for us, but sometimes SQL query is not that bad
Sometimes it's not about performance, some specific feature might not be translated yet by the EF Core provider
Would a Stored Proc be better?
I'm studying English a lot to be able to better understand your teachings! Your videos are great
Glad you like them!
I don't want to disappoint you but EF was always able to compete with Dapper! You just need to compiled (pre-compiled) linq query.
That would be too much work just to be on the same level. Don't you think so?
I hope this will get a query builder... I'm not too keen on writing big strings for querying in a code first approach.
Learn SQL 🤣
@@MilanJovanovicTech that's not the problem i mainly have. The problem for me is that it's hard coded and if, for some reason, someone changes the names of the properties, you have to manually change the occurrences by hand ✋
With Dapper or EF, never write SQL Queries in the code. Use stored procedures
How is that any better? This way at least I have them in source control
@@MilanJovanovicTech This is the work of a DBA not a developer. SQL is more complex than people think, there's a lot of things to think to get a better performance in SQL.. there's also tools in SQL to track performance and schema of a request.
And of course you can export a Schema File .SQL and you put that in Git to track changes.
Actually it's a simple request you do, but imagine when you work for a big company who have some requests of thousands of line.. it's better and safe and readable to put that in Stored procedures.
In my opinion there's two ways. Use code first like EF or use Dapper or EF with stored procedures.
Remember that as a Developer you should never assume risques of a DBA. Because you are not paid for, and you can be in a trouble if something is wrong in production.
Also, every developer should learn SQL server, no one can be a good developer without that.
But remember to let everyone assume his job. Because he knows How to do it in a good way.
@@MilanJovanovicTech Really? You don't know how much better Stored procs are over SQL statements....
That defeats the purpose of the ORM... With an ORM like EF you get platform independance, which means if you decide to migrate to a different DBMS, all you need to do is switch DB provider and connection string. If you write your application with a bunch of stored procs, you have to rewrite them. I work on ERP data systems with hundreds of tables and millions of records, the only stored procs or db triggers we use are for very specific things, like audit tasks, access control or user rights management, maintenance tasks, etc... Things that would be too complicated to do purely in EF, basically.
Very interesting, thank u! If we are getting nit-picky, there is the overhead of provisioning a dbcontext instance from the db pool every time you need to run a query. Whereas using dapper I would presume it wouldn't rely on as much resources, tho am only speculating here. Will look forward to seeing your benchmarks video!
The performance difference is quite minimal with the recent versions of EF
thanks for sharing
You're most welcome!
An awesome video, an awesome feature and awesome explanations! I've worked with Dapper for 2 years so it looks so intresting. You also can group data via sql script and miss linq grouping and selecting data
Grouping doesn't solve the problem here
Wow, that can truly put the need of the Dapper back. Also in this video a nice comparison of 2 libs can be seen and how much easier to query data using high level EfCore features and you get the model you need straight away
I didn't try composing the IQueryable further, but if that's possible it will be pretty good
awesome stuff.
Thanks :) I also released a video this week that covers this feature in detail
My problem with this approach in general is that you are returning a lot of duplicated data. In you example you are only returning a few fields from the order but what if you need more? Every field you add is duplicated for each line item. 1000 line items means you just transferred and loaded 1000 duplicate fields that are going to discard.
Then run two queries 🤷♂️
@@MilanJovanovicTech why not put the group by and aggregates in the SqlQuery ? so they are done at the db server side and save the network traffic volume at the cost of server CPU consumption.
@@joeng3385 And what do you get back from the DB?
@@joeng3385 You do not want an aggregate of the rows, you want all the rows so either you would need to run two queries, which adds overhead, or you do as the example in the video.
I do not know if EF_Core can use multiple results, but that would be a lot more complex query on the SQL side so unless its a lot of data from the order its probably not worth it.
And if it really is, then you probably want to make it into two separate queries and merge in C# instead
Writing short subtitles in the video seems a bit redundant when UA-cam can already do it automatically. Why not write the custom subtitles there?
Personally I find the in-video too-quick subtitles distracting.
It's a nice touch :)
Man this is the video I tell you. Looking forward to seeing what the benchmarks reveal especially now as my team will be doing a rewrite of one of our projects and we are still debating on whether to go EF Core or Dapper or both. 👀
Underwhelming, to say the least. Nick just did a benchmark video, and it's slower than Dapper and pretty much on par with EF LINQ.
I'll do another benchmark video in a few months, if I see some improvements are made to this feature.
I just find you searching about ddd, Great content, thanks
Glad you enjoy it!
If you're making a performance video, please also include linq2db with the different ways of writing the queries and optimizing it. At least that would be very interesting for me as I have used it in some projects, and like the abstraction level they have chosen (in between standard EFCore and Dapper).
+1. However I found linq2db creating queries which results were incorrect. However I use it for some features (window functions support, custom aggregate functions support, some patterns that efcore can't handle etc)
I'll consider it. But I haven't used linq2db before 🤔
If/when you do the comparison between EFCore 8 and Dapper. Can you include both the 'normal' linq approach vs the new raw SQL version in EF 8. I'd be interested in not only the time difference between EF and Dapper. I'm also very interested in understanding the different in times between the two EF approaches (both using EF 8 for a fare comparison).. and keep up the good work mate.
I ask as if the performance isn't 'worth' the extra code and hands off SQL vs LINQ approach.. readable and compile safe is my preferred option. I do agree that projection and other approaches to reduce the effort to produce results, at scale. The extra $$ to gain from unreadable code maybe not worth it. Except when it is 'worth' it.
Nice work!
+1 for mentioning linq2db i use it to handle bulk scenarios where we have to push tonnes of data rows around or when some special queries ef cannot handle like projected unions.
this great, as i know dapper does not have IQueryable return , i think this is a good advantage for the EF core 8, what do you think?
Right, the EF approach is more flexible in that regard
I really wish we could use EF Core but as far as I know, it does not support the database my company is stuck using - IBM for i or DB2 iSeries (or whatever it’s called these days).
To make it worse we are stuck on version v5r4! 😢
Does anybody know if EF Core can be used for this as I haven’t been able to find anything for years.
What about this: www.ibm.com/docs/en/db2/11.5?topic=adonet-data-server-provider-net-core
Nuget package is IBM.EntityFrameworkCore, been working for at least 2 years AFAIK...
Great video, thanks. Is it possible to achieve something like Dappers QueryMultiple in EF Core 8?
I don't think so 🤔 Will check
Was Theme are you using?
Visual Studio Dark theme + ReSharper syntax highlighting
I switched from EF to Linq2DB and never looked back. Can you compare the two with regards to ease of use, features and performance for some complicated queries? I am interested in your opinion.
I'll add that to my topic list 😁
Linq2SQL is fine if all you are doing is ad-hoc queries, but EF gives you atomic operations, proper complex type support, database generation from the model, loose coupling through dependency injection, etc...
We will see when performance benchmarks come around, but if it is the same as dapper it could absolutely kill it
I expect it to be close, we'll see 😁
Even if they're close, I'd probably still keep using Dapper. However, if they can get EF to use source generators rather than reflection, that would change the conversation.
@@reikooters They probably will sometime soon since more and more libraries use source generators now
Good video once again, But can you do a video with benchmarks of the performance to illustrate your point. Thanks
Will do!
but that's available in old EF6 not core.... lol didn't know EF Core was so limited
Yes, EF Core has been moving slowly
So much thought put into ORM frameworks, and in the end the developer still needs to write SQL queries by hand...
What's bad about that?
How is the one-line LINQ statement AsNoTracking by default ?
EF projections aren't tracked
You sure it's a new feature? This was already in the entity framework like 10 years ago! They're just brining it back to the Core.
I said "EF Core" didn't I? 😅
Would that mean that we finally can get dynamic queries (for example dynamic sorting) out of the box, without writing custom expressions or referencing 3rd party packages?
Can I combine "classic" lambda-style LINQ queries and have dynamic orderby with this?
I have not tried it, but since this returns an IQueryable in theory it should be possible. Going to explore the feature more to see if it's possible.
What benefit do you gain from dynamically sorting server side instead of just sorting the results of the query client side?
А тут на 39 строке в самом конце нельзя SingleOrDefaultAsync поставить? EF из за ToListAsync разве не должен по всем записям пробежаться?
You would get strange results - it's a JOIN which returns multiple rows from the DB. Single would only fetch the first row. Right?
EF Core's new feature may make it easier for developers to write raw SQL queries and map the results to objects, which was previously a strength of Dapper. However, this feature does not replace Dapper entirely.
Not yet, for sure. But as more features are introduced, we'll see how this will evolve.
Thanks for talking clearly, we all foreign can understand you perfectly!!!
Glad to hear that!
Great video Milan. I'm planning an app and I was thinking about using Dapper for reads and EF Core for writes. If this new feature in EF 8 has the same performance as Dapper I will consider it in the future.
I'll let you know as soon as I do the benchmark 😁
dapper is always faster
If you use store procs it’s even faster.
This is more like EF Core admitting defeat to Dapper by becoming like it.
EF 6 had this... It's just now coming to EF Core
Its more verbose, includes table Details, has a Bug (no items returned throws) and most likely isnt faster. Not sure it's worth the cost of loosing the Advantage of using EF Core even for Performance critical paths. Benchmarks is the first thing we should have done 😅
I'm pretty confident it'll be more be performant, but I'll let the benchmarks prove me wrong 😁
On the other hand, an order without any items sounds like broken data to begin with :)
But this is an example, probably not production level SQL code or mapping.
Nick Chapsas made a video about this feature and he did benchmark it. TLDR: Dapper is still faster and uses less memory. Going back to his earlier videos where he did compare dapper vs regular EF, raw sql in EF looks not that different from regular linq queries. At least for now.
@@dsvechnikov If you precompile and cache your EF queries, there is basically no difference in performance, or memory usage...
Thanx a lot,
It's a really nice feature explanation.
Keep going, you are awesome 🔥
Thanks a ton
A bit late, but I like Insight.Database library a lot due to its excellent and complex object mapping features. In this example, with InsightDatabase there would be no grouping necessary.
Never heard of it, looks interesting!
Hi Milan, is there a way that we can constraint the IApplicationDbContext only for AggregateRoots? Because i like using this feature instead of repositories but i want to constraint that only the ARS can access the iappdbcontext
You can simply expose only the DbSet of the aggregate roots
couldnt this already be done with EF Core Views?
But you need to add them as keyless entities
Really nice video .. but when i use long string sql queries inside the code I feel little ugly the code looks . Is there any better way for that 😂
I like SQL 🤷♂️
stored procedure
EF Supports this feature, I'm not sure if EF core didn't support it before EF core 8
This is what I was going to say. I don't understand why they removed this feature in the first place. Before 8, EF Core made us add the unmapped entity as a dbset, which seems silly. I am glad they're putting it back, though; I have a project that needs to be moved to .NET Core, and this solves one of the major problems.
There's probably a good reason for that 🤷♂️ Or just lack of engineers to ship this until now.
Hello Milan! interesting video, I am currently using Dapper and SqlKata and extending some methods for SqlKata to be able to use them with my entities without having to write the raw query, for example:
var result = _repoQuery.GetQuery()
.SelectRaw(columnNames)
.Where(nameof(TemplateType.ClassId), classId);
I hope to be able to do something similar with this new feature. Thanks for your content!
Why not just write SQL? 🤔
@@MilanJovanovicTechby example: names of tables, schemas or columns are different in my models and database
@@WillmanForeveruse alias..
We're not allowed to use inline sql like that we can only use parameterized queries so how can you do what you just did but parameterized?
It is parameterized 😅 It "looks" like an interpolated string, but the argument is actually converted into a SQL parameter. That's how the FromSqlRaw methods work.
@@MilanJovanovicTech oh nice.
I didn't understanded everything, maybe because I'm new at C#, but I think I could deal better with the second approach using EF 8.
The one with LINQ projections?
Well it does not look like dapper replacement. What if you need to get more than 1 dataset from db, you would join all them to 1 result dataset? Also what if you need to put as a parameter user defined data type? What if you need to get back dataset plus return value from stored procedure?
I moved to dapper about 8 years ago, and do not see alternatives for it at least on my project. I mean ef even not close to all dapper functionality.
Multiple result sets (or MARS) is a SQL Server specific feature. In any other case, it's just multiple SQL queries in multiple round trips.
What about parameterize query ? Is it safe from SQL Injection ?
The example I showed is parameterized
@@MilanJovanovicTech How is it it parameterised, you just used string interpolation to inject the string into the SQL string. that is not parameterised.
code in 189% it's look very clear. All other thing are almost imposible to see.
Then we need to see it full screen and that make the code to big.
The struggles of making coding tutorials 😅
I have a process such as adding 100 thousand records to my MsSql database at once, using an entity framework with a loop. This works successfully at low numbers, but is there any timelout in such large numbers? How can I make this happen in a healthy way?
Bulk insert maybe?
@@MilanJovanovicTech This really works. It really surprised me how fast it added 100k of data. Thanks.
I was interested in the new feature of EF, but do you REALLY believe Dapper will be displaced so easily? If so, you are incredibly naive. No like or subscribe here. Perhaps if you drop the click bait, and have a performance comparison. But “probably” won’t begin to sway others. And the feature is far from those I use regularly in Dapper.
Dapper isn't getting many new features. EF is rapidly innovating. Give it some more time :)
Hello milan thanks for you efforts, one of the best content creator in my opinion
i have a question let's say that in the same app i want to add the categoriesto the product
then, as in the diagram you provided serveral videos ago what should it be defined as an aggregate root or it's an entity
and if it's an entity how can i add the management endpoints to it like add delete and so on because it will belong to some aggregate root,
on the other hand if it was an aggregate root
i tried to add a list of it's ids to the product aggregate but couldn't figure out how to configure it with ef
can you make a video about simillar scenarios or something like that
thanks again ♥
The problem is you're thinking about it from a CRUD perspective.
A Category is most likely a standalone entity in your domain.
Products can belong to one or more categories.
So just configure a one-to-many relationship on the Product side.
@@MilanJovanovicTech i see that make sense thank you
Slapper is a cool library that can do that grouping of child records based on ID and return a complex type that pairs very well with Dapper. You just get a list of dynamics from Dapper and feed it to Slapper and if your fields are named right (or you can manually teach it a mapping) it will handle the mapping for you. Works great if you change your types, no need to refactor the mapping code. If EF Core 8 supports reading results from the DB into dynamic it should pair just as well.
Overall, if you prefer the Dapper approach I don't see this as a reason to stop using Dapper. It's just copying Dapper and letting that functionality exist alongside traditional EF. If you don't like EF to begin with (like me) - why not just keep using Dapper?
Of course. I'm an EF fan, but I don't mind Dapper at all. I'd prefer to have everything in one library.
hi. I think this type of query can lead to sql injection. is there any way to do prepare statement like dapper does?
It won't. It's parameterized.
Why do you need EF Core to write pure SQL?
The power of EF Core is to write strongly typed queries and to detect errors in a query at the compile time.
There's also the flexibility to write raw SQL for performance reasons
There is no reason to use dapper now, 2 weeks ago I was wondering about it, how was possible I cannot to make a raw query without to specify an entity dataset. The Microsoft God listened my thoughts .
You called it! 😁
Dapper is lightweight
Not just about the features
That is true
Amazing!
Thanks!
very informative can you make a tutorial for developers new to C# and NET please?
There are plenty of decent channels out there, Milan makes great content for intermediate developers looking to advance their skills
As Myles said, there are awesome channels out there and my target audience are is for more advanced engineers 😁
Its nice to have but i dont see that replacing dapper...
No dapper project ever broke on an upgrade, cant say the same for the ef projects - especially with posgres this was a nightmare for some projects.
Maybe. But if you're already using EF, it solves many use cases that you would previously use Dapper for
Great content. I have one question and that is why you used record instead of class in this video?😅
Just for fun, mostly 🤷♂️
This thing is somethong you can do in NHibernate since around 20 years.
EF Core is a bit late to the party
@@MilanJovanovicTech what I mean is that "EF Core Feature Be The End Of Dapper" is not a good title. They are all tools, is similar to saying that because you now have philips screwdrivers you don´t need plain screwdrivers.
Well, it seems that now is better than Dapper but not than RepoDB
RepoDB isn't widely adopted
@@MilanJovanovicTech So do you mean that just because it is not popular enough for you it doesn't matter that is better?
@@AlfredoPinto Did I say that? No. So, why place words in my mouth? Weak argument... Any speed improvements these ORMs can make will be on the processing side, which is pretty non-impactful. The majority of a query costs will be the network roundtrip time and the work done in the DB.
@@MilanJovanovicTech yes, you are right, you don't say that. But is not about how fast or slow the queries are executed compared to EF and Dapper that makes RepoDB an excellent ORM. What I am saying is that you judge it and discard it without know it, so I got the impression that you do that was just because it wasn't a popular ORM.
@@AlfredoPinto I researched it a bit in the past, but never ended up using it on a real project. I remember it had some feature limitations. Will check if that's been fixed now.
Honestly , never been a fan of dapper ... I am glad ef core's performance is improved
Haven't done the benchmark, but I expect them to be pretty close
@12:40 - what an excellent way to get SQL Injection. don't insert parameters like that.
I see you have no idea how this feature works, or didn't bother hearing my next sentence 😁
@@MilanJovanovicTech Correct. I'm still using EF 6 (work hates upgrading). so yea, still new to me. I'm really surprised that this is actually parametised. It just looks so wrong compared to what we do.
@@harag9 There's FromSqlInterpolated I believe in that version 🤔
No, EF Core sucks for some complex tasks
No it doesn't
EF Core to the very last
Die hard fan? 😁
👍😀
ADO would have been faster and more clear
Are you sure about the more clear part?
I'll use dapper until EF Core 8 stable comes out.
Sounds like a plan
🚀
Wonderfull video
Many thanks! :)