EF Core In The CQRS Query Side... Or Something Else?

preview_player
Показать описание

CQRS is a hot topic these days and paired with the Clean Architecture, it makes for an excellent development approach. But with Clean Architecture being so prescriptive about design and persistence ignorance, it begs the question: is attracting away the CQRS query side worth it? In this video, I'll show you how to implement the query side in a persistence-ignorant way. And I'll discuss the pros and cons of each approach. I'll let you decide if it was worth it in the end.

Join my weekly .NET newsletter:

Read my Blog here:

Subscribe for more:

Chapters
0:00 Using EF Core directly
1:32 Persistence ignorant query side - Read service
5:14 Implementing the Read service with EF Core
9:42 Read-service per query (Vertical Slice)
Рекомендации по теме
Комментарии
Автор

I prefer not to have the ReadServices. I usually place the query directly in the QueryHandler because most of my queries are intended for the front-end only. The resulting data is often specific to the front-end requirements. Instead of having one method in the ReadService for each front-end requirement, I prefer to simplify by placing the code solely in the QueryHandler.

Ukyron
Автор

Is creating the query handler in the data layer where it will have access to the context a viable option?

farlloncosta
Автор

6:31 SingleOrDefault method will not throw an ex if no records are found in the db - it will return null. it is true only for the Single method

thshr
Автор

What about implementing a second DbContext as a "read only" context, which basically exposes every entity (table) instead of just the aggregate roots? Is this a viable option? I've recently run into this problem of DDD and queries when I want to retrieve entities that belong to an aggregate, but I don't want to fetchs all the aggregates just to return a flattened list of their children.

zagoskintoto
Автор

Thanks for the video. This is exactly how i like to structure my project. I apply CQRS as a concept of separation of command and read hence i have a service for command (OrderCommandService) and read (OrderReadService). By extension, i just inject the necessary service in handler if i need to use mediator (this may seem wrong combining ServiceClass and Handler but as Milan pointed out, there might be need to introduce some other logic directly in handler)

usmy
Автор

One question please Milan, why do you make an abstraction for ApplicationDbContext although we can inject it directly ?

ramytawfik
Автор

Like in your current example with repositories, when we have so many repsositories in our project, we have to add each one of them as services.AddScoped, is there any better way to just include a single file who have all this repositories objects in it, or the way you have shown us, is better and more readable and easy to manage or have better control. Please share your opinion. Thanks as always?

atifsaeedkhan
Автор

Thx for the vid, quick question, why is this a "service" in the persistence layer rather than a "repository". Always been a little confused on the conceptual difference in this context.

xnn
Автор

Also why you create IOrderReadService in the application Layer not in the Domain Layer ?

ramytawfik
Автор

Very interesting content. Thank you Milan

kodindoyannick
Автор

Why do you need a leaky abstraction (IApplicationContext) in an abstraction (service) in a abstraction (handler)? Imo it should be enough to have a single abstraction like a handler or a service, but not both.

Rookiande
Автор

Nice summary of pros/cons of each approach. Curious on your opinions of Ardalis's Specification package (if you're familiar with it).

silvertek
Автор

You changed from SingleOrDefault to FirstOrDefault saying SingleOrDefault throws an exception if no item is found but it's wrong, Single does it, but SingleOrDefault return a default value, in the case it's null if no item is found, it will throw an exception if the query returns more than one item, while FirstOrDefault doesn't throw if more than one item is returned returning the first item found

In my view it's wrong to use First/FirstOrDefault if the query should always return a single item, in the case as you are filtering by Id it should never happen, but if you make a mistake and somehow forget to filter by the id you could get the wrong result

LeandroAGR
Автор

The main revelation for me regarding CQRS is that it is OK to bypass the repository thing when just retrieving data. You can simply just retrieve whatever you need from the database. It doesn't have any side-effects.

marna_li
Автор

First of all thanks for the video. I'm new to all of DDD, CQRS, Clean Architecture and I have some things that I don't understand, and on this topic is why in the commands we do use the interfaces of the repository pattern and not, for example, use EF directly? How is it different from reading?
Until today, I thought that a repository was mainly intended to create an abstraction between the logic and the database, for the option to easily replace the implementation of the database, and here if it depends directly on the DB, how is it possible to make a replacement?
In addition, the software I'm building has a lot of complex queries with a lot of logic, and that's probably why I'll also separate the DB for writing and reading, and there are still things I don't understand
Like the one that I thought that the domain model is the one responsible for all the logic in this architecture and on the other hand I realized that it is only responsible for the commands so it turns out even if I have a lot of complex queries (Like in my case, for example, the user asks to see rental cars + price offers, which should include complex algorithms, and there are many more of them) So it turns out that I have to do a lot of logic on the side of the query and it seems strange to do all this inside the handlers of the queries, it violates the SRP Absolutely, so what do you do in such cases? I would appreciate it if you could answer me.

Yehuda-Shor
Автор

I prefer write queries on handler. It's more flexible for queries. I can write queries using ef core, dapper, ado... Depending of necessity of some handler.

jezielmoura
Автор

Good video, but If you use services with interfaces, maybe it doesn't make much sense to use MediatR as a wrapper.

Автор

I have an irrelevant question. Can you share your code theme? It looks really nice. And awesome video as always.

brkkaraaslan
Автор

Hi Milan, What visual studio theme are you using

HelloWorld-thvb
Автор

Why is the GetById method in the repository bad? CQRS broke?

TheAlien
join shbcf.ru