You're very welcome! Glad they're working well for you. There are always some who say they won't work but I haven't run into any significant pain points in the many apps I'm using them in.
@@Ardalis Our only pain point was temporal table specifications that aren't supported out of the box, but we were able to easily extend the library by adding our own.
Hello everything is fine? I am using the Specification package in my projects and it is working perfectly. I would like to know if I can work with joining specifications with the operators And, Not, Or. Thank you.
Hello sir, i am trying to approach a different way to relational database which means i want to apply inner join for no sql instead of relational database? Because relational database will be low performance when there are a lot of data. Thank you and best regards
Good luck but I'm not sure this video is relevant to your needs. If you are using a relational database and your joins are slow because of too much data, one option is to denormalize the data, which is basically the technique a no-sql database would use, too.
Hello, I was wondering if you're familiar with Odata which is similar to graphql; why would one choose to go with this specification pattern instead of something like Odata?
Yes, OData is quite different from specifications, conceptually. OData is about exposing your database over HTTP. In that way you're correct, it's like GraphQL. In either case, it lets the consumer of the web service (via OData/GraphQL) create whatever queries they want (within the supported set) and the server basically just executes the queries it is sent. Using specifications implies that you're going to have a discrete set of operations that your application uses, and you want to treat them as part of your business logic / domain model. Thus, you don't let *even your own application* (much less random clients on the web) generate custom queries, because you want to ensure the queries are correct and that they are reused where appropriate (you don't want two different versions of a query that should logically return the same results, for example). Hope that helps.
Hi, I am using your clean architecture sample ! Seem, project Specification.EntityFrameworkCore just implemented Repository pattern. You SaveChangesAsync affter Func CUD called ( _dbContext.Set().Add/Remove/Update). But in Repository pattern I referenced, it implements IUnitOfWork. Why u use repository pattern without IUnitOfWork in your clean achitecture sample? If I use IUnitOfWork, what is need I Do? Looking forward to your response, Thanks and have a nice day !!!
The repository sample implementation in Ardalis.Specification is optimized for simple Web APIs which typically only modify a single aggregate in a given CUD request. Thus, it simply saves changes implicitly any time you call one of its Add/Update/Delete methods (instead of using or exposing a separate Unit of Work). It's simple. If it's *too* simple and you need a separate unit of work, you can use your own abstraction. The simplest approach would be to just expose SaveChanges on your repository abstraction and do NOT automatically call savechanges in your CUD methods. But this is only a very simple version of Unit of Work since it's possible for you to have separate repositories working on separate aggregates and then when you call SaveChanges on one of them, the other's modified entities will also be persisted (which may not be what you wanted). So an even more complex approach is to have a separate UnitOfWork type that manages all of your persistence. Often when using this approach you need to request your repository instances from the UnitOfWork, and then when you're ready you Commit on the UnitOfWork and any repositories that came from it are likewise committed (but those from separate Units of Work are not). Hope that helps.
Not compared to just using EF6/EF Core, that I'm aware of. And the built-in caching features obviously dramatically improve performance if you can and do use caching.
Where can i use .AsNoTracking() method using your library? I mean i keep getting error about tracking when trying to update an entity that i have already get. var existCategory = await _categoryRepository.GetByIdAsync(request.Id, cancellationToken); Guard.Against.NotFound(request.Id.ToString(), existCategory, nameof(existCategory.Id)); var categoryToUpdate = _mapper.Map(request); await _categoryRepository.UpdateAsync(categoryToUpdate); - here
Your error is in your mapping line - you're getting a new entity not updating the one you fetched. Update the one you fetched instead. Also to answer your question, you can use AsNoTracking within your specification, but it won't fix your problem. specification.ardalis.com/features/asnotracking.html
Been using your repositories and specifications in Production since beginning 2022. It's just so easy to implement! Thank you.
You're very welcome! Glad they're working well for you. There are always some who say they won't work but I haven't run into any significant pain points in the many apps I'm using them in.
@@Ardalis Our only pain point was temporal table specifications that aren't supported out of the box, but we were able to easily extend the library by adding our own.
As expected from Ardalis, always substantial. Thank you.
Thank you too!
just what's needed. nothing more - nothing less. thank you.
Awesome, that's the goal!
Greate job ! I think, we need more of your videos, how to use your libs in specific scenarios.
More to come!
Great video. Matured stuff. Steve will direct you to always do the right thing. Thank you Sir, I am grateful 🙏 .
I appreciate that!
Thank you. Very helpful. Just learning about specifications.
Glad it was helpful!
Great stuff! 👍
Thank you! Cheers!
Can you also implement bulk Crud operations? Thanks
yes but that wouldn't warrant specifications. EF supports these as does raw SQL...
Hello everything is fine? I am using the Specification package in my projects and it is working perfectly. I would like to know if I can work with joining specifications with the operators And, Not, Or. Thank you.
No, that's not supported and not recommended (but it is frequently requested). See: github.com/ardalis/Specification/issues/335
Hello sir, i am trying to approach a different way to relational database which means i want to apply inner join for no sql instead of relational database? Because relational database will be low performance when there are a lot of data. Thank you and best regards
Good luck but I'm not sure this video is relevant to your needs. If you are using a relational database and your joins are slow because of too much data, one option is to denormalize the data, which is basically the technique a no-sql database would use, too.
Hello, I was wondering if you're familiar with Odata which is similar to graphql; why would one choose to go with this specification pattern instead of something like Odata?
Yes, OData is quite different from specifications, conceptually. OData is about exposing your database over HTTP. In that way you're correct, it's like GraphQL. In either case, it lets the consumer of the web service (via OData/GraphQL) create whatever queries they want (within the supported set) and the server basically just executes the queries it is sent. Using specifications implies that you're going to have a discrete set of operations that your application uses, and you want to treat them as part of your business logic / domain model. Thus, you don't let *even your own application* (much less random clients on the web) generate custom queries, because you want to ensure the queries are correct and that they are reused where appropriate (you don't want two different versions of a query that should logically return the same results, for example).
Hope that helps.
Hi, I am using your clean architecture sample !
Seem, project Specification.EntityFrameworkCore just implemented Repository pattern.
You SaveChangesAsync affter Func CUD called ( _dbContext.Set().Add/Remove/Update).
But in Repository pattern I referenced, it implements IUnitOfWork.
Why u use repository pattern without IUnitOfWork in your clean achitecture sample?
If I use IUnitOfWork, what is need I Do?
Looking forward to your response, Thanks and have a nice day !!!
The repository sample implementation in Ardalis.Specification is optimized for simple Web APIs which typically only modify a single aggregate in a given CUD request. Thus, it simply saves changes implicitly any time you call one of its Add/Update/Delete methods (instead of using or exposing a separate Unit of Work). It's simple.
If it's *too* simple and you need a separate unit of work, you can use your own abstraction. The simplest approach would be to just expose SaveChanges on your repository abstraction and do NOT automatically call savechanges in your CUD methods. But this is only a very simple version of Unit of Work since it's possible for you to have separate repositories working on separate aggregates and then when you call SaveChanges on one of them, the other's modified entities will also be persisted (which may not be what you wanted).
So an even more complex approach is to have a separate UnitOfWork type that manages all of your persistence. Often when using this approach you need to request your repository instances from the UnitOfWork, and then when you're ready you Commit on the UnitOfWork and any repositories that came from it are likewise committed (but those from separate Units of Work are not).
Hope that helps.
does the Ardalis spec package cause any performance overhead?
Not compared to just using EF6/EF Core, that I'm aware of. And the built-in caching features obviously dramatically improve performance if you can and do use caching.
Does this nuget work with MongoDB?
The base package yes but there’s not a translation package for MongoDb (yet).
Super
Thanks
googlebing?
No, I duck that. :)
DDG also works :)
Where can i use .AsNoTracking() method using your library?
I mean i keep getting error about tracking when trying to update an entity that i have already get.
var existCategory = await _categoryRepository.GetByIdAsync(request.Id, cancellationToken);
Guard.Against.NotFound(request.Id.ToString(), existCategory, nameof(existCategory.Id));
var categoryToUpdate = _mapper.Map(request);
await _categoryRepository.UpdateAsync(categoryToUpdate); - here
Your error is in your mapping line - you're getting a new entity not updating the one you fetched. Update the one you fetched instead. Also to answer your question, you can use AsNoTracking within your specification, but it won't fix your problem.
specification.ardalis.com/features/asnotracking.html
@@Ardalis i see. Thank you big time!