Timeline for Repository Pattern and Joined Queries
Current License: CC BY-SA 4.0
19 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Dec 2, 2019 at 14:41 | vote | accept | gilliduck | ||
| Jul 20, 2018 at 1:21 | comment | added | Fabio | @Flater, again you are using very generic examples. Programming is all about context and only when you have context related solutions you can see patterns/abstractions. Come up with more specific example of IsBar and I will try give you example how it could be implemented. | |
| Jul 19, 2018 at 20:55 | comment | added | Flater | @Fabio You're still not getting the loint that IsBar is a piece of logic, not just a simple value. You keep contradicting your previous statement whenever a flaw is presented in what you said, making this a futile exercise. | |
| Jul 19, 2018 at 20:03 | comment | added | Fabio | @Flater, again no(sorry :)), repository methods will not take expressions as arguments, but just values, where repository will decide in which expressions it should be used. Expressions behave differently in EF, so exposing them to domain logic, will be leaking implementation details. | |
| Jul 19, 2018 at 20:00 | comment | added | Fabio | @Flater, but then you're contradicting yourself - no, type name will provide information about what kind of data returned from the method: "Statuses requested by user". | |
| Jul 19, 2018 at 14:43 | comment | added | Flater | @Fabio I will pass result of IsBar to repository as argument Sure, but then you're contradicting what you said with Main responsibility of Repository pattern to abstract actual database from domain codebase. because the repository's consumer is now required to know the underlying filter. If your repository takes in Expression<Func<T,bool>> blindly, so as to facilitate filtering; then the repository's only remaning job as an intermedary layer is to join/include other entity data, which is the one thing repositories are notoriously not built to inherently handle (due to OP's reasoning). | |
| Jul 19, 2018 at 14:41 | comment | added | Flater | @Fabio: Sure, you can load statuses optionally, but then you're contradicting yourself when you said For example domain object order with empty collection of lines, can lead in wrong assumptions that order doesn't have lines. You're either going to have 8 DTO classes so you pick the right one and do not leave nulls; or you make a single DTO class and pass null. | |
| Jul 19, 2018 at 13:39 | comment | added | Fabio | @Flater, I will pass result of IsBar to repository as argument and filter results based on the parameter value. | |
| Jul 19, 2018 at 13:37 | comment | added | Fabio | @Flater, it is difficult to tackle generic problems without context and usage examples. With given information, I would create a type which clearly states that loaded data requested dynamically, for example - FooWithStatusesRequestedByUser where statuses will be properties with optional type. Then repository method will accept argument with requested statuses and load only requested data. | |
| Jul 19, 2018 at 13:18 | comment | added | Flater | @Fabio: Read data and Save data. So IsBar logic will be outside of Repository Keep in mind that IsBar can be part of the fitler logic of a data read. So when you need to load all Baz objects and include all Foos where IsBar is true, would you then not be stuck loading all Foos and then only filtering in memory? (or, alternatively, loading the foos at a later stage and not in the same query) | |
| Jul 19, 2018 at 13:14 | comment | added | Flater | @Fabio: (in response to your response to Ewan) How do you handle optional loads? E.g. I've had cases where a Foo entity had 3 separate status objects. All these statuses were optionally loaded (sometimes we needed one status, sometimes two, sometimes all three), thus creating 8 different combinations of (un)loaded statuses (YYY, YYN, YNY, YNN, NYY, NYN, NNY, NNN), and subsequently 8 different FooWith... dto classes. Houw could you combat that? | |
| Jul 19, 2018 at 12:58 | comment | added | Ewan | @Fabio yes, I think you are right in that, its only a small niggle on my part. see my answer for my alternate approach. ie get the lines as a separate list when needed | |
| Jul 19, 2018 at 12:54 | comment | added | Fabio | @Ewan, this was just an example with poor naming, but I prefer to explicitly "tell" what I am expecting from particular method. For example domain object order with empty collection of lines, can lead in wrong assumptions that order doesn't have lines. And loading lines only to satisfy domain object when I need only basic info about order looks resource wasting. | |
| Jul 19, 2018 at 12:47 | comment | added | Fabio | @Flater, I will have separated repository classes for CRUD operation and complex data queries. Repository executes only operations which database is responsible for: Read data and Save data. So IsBar logic will be outside of Repository. | |
| Jul 19, 2018 at 12:47 | comment | added | Ewan | My niggle with this approach is that your repo is returning DTOs, of which you have two for the same thing, rather than Domain Objects. Its easy to inflate into SaleOrdersWithLinesAndTransactions, SaleOrdersWithCustomerButNoLines etc etc | |
| Jul 19, 2018 at 12:30 | comment | added | Flater | How do you handle needing both entity-specific operations (e.g. an MVC backend that allows CRUD on tables, one entity at a time, which would require entity-specific repositories) and the abstracted operations (which operate on more than one entity type, thus using your absracted repository suggestions)? Create both types of repositories? How do you then avoid WET when Foo has a certain IsBar logic that needs to be used both in the specific FooRepository and the abstracted FooAndBazRepository? | |
| Jul 19, 2018 at 8:35 | comment | added | JᴀʏMᴇᴇ | Interested to hear why this was downvoted? So, instead of mirroring database structure in your repository, have abstractions which fit domain needs. Spot on, +1. | |
| Jul 19, 2018 at 8:20 | history | edited | Fabio | CC BY-SA 4.0 | added 7 characters in body |
| Jul 19, 2018 at 2:08 | history | answered | Fabio | CC BY-SA 4.0 |