Repositories are great, until you need specialised functions, and then you end up with fat-repositories. EF Core already implements repository pattern as well as UoW. So one just end up with an abstraction on top of an abstraction. I just use DbContext directly. It saves me heaps of time.
@OeHomestead @DanWalshTV You both bring up some solid arguments! Using the DbContext directly can definitely save time in many cases. However, I think repositories can still have their place when it comes to reusability and keeping application layers decoupled. It can be helpful if you need specialized methods or want to reuse data access logic across different parts of a larger application. But for simpler projects, DbContext directly can be the way to go!
10 years ago I forced repos/UoW on my team on a massive development and I would now say no! You lose IQueryable advantages (LINQ will optimize projections, sorting/filtering /paging by grids/views) and end up with so many custom retrieval functions when joining. Developer velocity is drastically reduced and debt accumulated. If you have a simple siloed out data structure, sure use it but it is unnecessary abstraction with EF. If doing direct db access or want to abstract external data retrieval , absolutely use it
@@PatrickGod I agree, for simpler projects a dbcontext in the controller is fine, but for enterprise application I not only create repositories to handle my CRUDs, but inject that into another services abstraction that will include business logic and complex data returns. I find that makes managing and maintenance of large code easier.
Please: seperation of concerns. Do NOT call save after add! What if you want to add a character and some additional data in a transaction? Add is another concern as saving! Also: if your method is update (do it) but the object does not exist then throw an exception! If your code can not do what it was expected to do this is an exception! Otherwise the caller will never know if something was ever changed as desired. This is VERY confusing for someone to read later. 😮 and to transfer the properties from one instance to another either user and automatic mapper or write a dedicated method for the object class!! Else you will add a property later and you will forget that in your repository you need to change the update code.
As others have mentioned, EF is your repository. Or if you use Dapper or nHibernate, etc. that is your repository. What you’re creating is a DB service layer. Service classes encapsulate and abstract access to any resources outside your application such as DB, file, network, message queue, and so on. Even if you don’t use a ready made ORM and roll your own repository using ADO, if your application isn’t fairly simple, you’re going to end up writing lots of boilerplate and still want to make the repository more generic and lower level with a higher level DB service layer on top made up of service classes for various things, generally one per table or logical entity. A lot of people confuse repositories and service classes. They can be merged into one for simple use cases but if you are using an ORM like EF and creating specific DB interaction logic, that’s a service and EF is your repository.
@@eduardrivas6964 You’d just update your service layer in that case, which you’d have to do anyhow if you’re changing how you query the database. Having a repository around your repository doesn’t change that.
@@JohnSmith-op7ls My service will call the implementation of the interface of the repository, I would only need to change the repository implementation without touching the service at all. That's what I mean.
I'm with you. I reserve my repositories for the CRUDs and add another services abstraction for my busniess logic, like when I need to combine different data into complex results for the UI layer.
Thanks Patrick, can you explain a bit more about the line "return CreatedAtAction(nameof(GetCharacterById), new {id = character.Id}); ? I would have just returned the character object that was passed into the method, what does CreatedAtAction do in this scenario and what advantages are there in using it over just returning the object you inserted into the database?
And if you have defined a method to get a db object by id in your repository you should consider using it in update and delete. Else you might create inconsistent semantics
This is a very Hello World demo where a lot of context is lost when appkying this to a real world application. A lot of things have already been said in the comments. I dislike this type of video as it does not really techt or show anything that can be applied in practice
EF is a repository. To update an entity, simply do this. var oldNote = await _context.Notes.SingleOrDefaultAsync(n => n.NoteId == record.NoteId && n.SubscriberId == record.SubscriberId); if (oldNote != null) { try { _context.Entry(oldNote).CurrentValues.SetValues(record); _context.Entry(oldNote).State = EntityState.Modified; await Task.Run(() => _context.Notes.Update(oldNote)); var result = await _context.SaveChangesAsync();
Instead of .Find(); I use .Where(x => x.id == id).FirstOrDefault(); ... is there any difference in performance, or memory management by using .Find() or is it just for less code?
Repositories are great, until you need specialised functions, and then you end up with fat-repositories. EF Core already implements repository pattern as well as UoW. So one just end up with an abstraction on top of an abstraction. I just use DbContext directly. It saves me heaps of time.
Yup, exactly. If you're not using EF Core, then sure, but adding a repository pattern around EF is just pointless abstraction.
do you not think this makes unit testing tougher?
@OeHomestead @DanWalshTV
You both bring up some solid arguments! Using the DbContext directly can definitely save time in many cases. However, I think repositories can still have their place when it comes to reusability and keeping application layers decoupled. It can be helpful if you need specialized methods or want to reuse data access logic across different parts of a larger application. But for simpler projects, DbContext directly can be the way to go!
10 years ago I forced repos/UoW on my team on a massive development and I would now say no! You lose IQueryable advantages (LINQ will optimize projections, sorting/filtering /paging by grids/views) and end up with so many custom retrieval functions when joining.
Developer velocity is drastically reduced and debt accumulated. If you have a simple siloed out data structure, sure use it but it is unnecessary abstraction with EF. If doing direct db access or want to abstract external data retrieval , absolutely use it
@@PatrickGod I agree, for simpler projects a dbcontext in the controller is fine, but for enterprise application I not only create repositories to handle my CRUDs, but inject that into another services abstraction that will include business logic and complex data returns. I find that makes managing and maintenance of large code easier.
Please: seperation of concerns. Do NOT call save after add! What if you want to add a character and some additional data in a transaction? Add is another concern as saving! Also: if your method is update (do it) but the object does not exist then throw an exception! If your code can not do what it was expected to do this is an exception! Otherwise the caller will never know if something was ever changed as desired. This is VERY confusing for someone to read later. 😮 and to transfer the properties from one instance to another either user and automatic mapper or write a dedicated method for the object class!! Else you will add a property later and you will forget that in your repository you need to change the update code.
DbContext is the repository, you wrote anti pattern. Just inject the dbcontext to the Service classes.
And we’re back at Spring Data, good stuff, what’s matured is now finally accepted 🎉
As others have mentioned, EF is your repository. Or if you use Dapper or nHibernate, etc. that is your repository.
What you’re creating is a DB service layer.
Service classes encapsulate and abstract access to any resources outside your application such as DB, file, network, message queue, and so on.
Even if you don’t use a ready made ORM and roll your own repository using ADO, if your application isn’t fairly simple, you’re going to end up writing lots of boilerplate and still want to make the repository more generic and lower level with a higher level DB service layer on top made up of service classes for various things, generally one per table or logical entity.
A lot of people confuse repositories and service classes. They can be merged into one for simple use cases but if you are using an ORM like EF and creating specific DB interaction logic, that’s a service and EF is your repository.
just another name. it abstracts read and write from other business logic like can access
@@nothingisreal6345 No idea what you said
It may be until you need to replace the repository's ORM, for, let's say Dapper, then it's better to have it all decoupled.
@@eduardrivas6964 You’d just update your service layer in that case, which you’d have to do anyhow if you’re changing how you query the database. Having a repository around your repository doesn’t change that.
@@JohnSmith-op7ls My service will call the implementation of the interface of the repository, I would only need to change the repository implementation without touching the service at all. That's what I mean.
Hi Pat,
Do you think repository pattern can be combined with repr pattern for minimal api? Thank you so much for noticing and answering
Repositories in a Class library Along with a separate class library for business layer will make your project more cleaner and professional isn't it?
I'm with you. I reserve my repositories for the CRUDs and add another services abstraction for my busniess logic, like when I need to combine different data into complex results for the UI layer.
Thanks Patrick, can you explain a bit more about the line "return CreatedAtAction(nameof(GetCharacterById), new {id = character.Id}); ? I would have just returned the character object that was passed into the method, what does CreatedAtAction do in this scenario and what advantages are there in using it over just returning the object you inserted into the database?
And if you have defined a method to get a db object by id in your repository you should consider using it in update and delete. Else you might create inconsistent semantics
Question when we muti model save when on save update multiple table involved will it be useful
Hey Patrick i applied to your job. Your description said that I should contact you here
modern EF is already your repository. avoid the accidental complexity - don't introduce new concepts, as it is very easy to make things very complex.
Repositories would exceptionally well with minimal API's as well. We use this structure all the time now.
I can also only recommend using repositories, which is beautiful, simple and easy to understand software design.
Experts know when and when not to use a repository …
Grüße in den hohen Norden, aus dem tiefen Süden!
This is a very Hello World demo where a lot of context is lost when appkying this to a real world application. A lot of things have already been said in the comments. I dislike this type of video as it does not really techt or show anything that can be applied in practice
EF is a repository.
To update an entity, simply do this.
var oldNote = await _context.Notes.SingleOrDefaultAsync(n => n.NoteId == record.NoteId && n.SubscriberId == record.SubscriberId);
if (oldNote != null)
{
try
{
_context.Entry(oldNote).CurrentValues.SetValues(record);
_context.Entry(oldNote).State = EntityState.Modified;
await Task.Run(() => _context.Notes.Update(oldNote));
var result = await _context.SaveChangesAsync();
Instead of .Find(); I use .Where(x => x.id == id).FirstOrDefault(); ... is there any difference in performance, or memory management by using .Find() or is it just for less code?