Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TResource type differing from IQueryable type. #794

Closed
wasabii opened this issue Jul 28, 2020 · 3 comments
Closed

TResource type differing from IQueryable type. #794

wasabii opened this issue Jul 28, 2020 · 3 comments

Comments

@wasabii
Copy link

wasabii commented Jul 28, 2020

I am not using Entity Framework, since I do not want to couple my resource model to the underlying data model. As such, I am implementing a custom IResourceRepository<TResource>.

The IResourceRepository essentially allows you to compose up an IQueryable, applying filters, and sorts, to the underlying data source. Each method takes an IQueryable, and then returns an IQueryable. However: I do not intend to actually use this IQueryable as the final result. I would like the ToListAsync method to have a different return type.

The IQueryable can be used to compose up EF Core operations, like filters, or whatever, but then the final transformation of the data into a Resource should allow me to transform the IQueryable. Essentially, the IQueryable should not necessarily be the TResource type. I think it would make more sense if the interface was instead IResourceRepository<TResource, TQueryable>. That way each of the composition methods (Get, Include, etc) would shape the IQueryable, but the final ToListAsync method could transform that into the actual resource type.

Thoughts?

@bart-degreed
Copy link
Contributor

Projecting into a different storage data shape in general is a hard problem to solve. EF Core provides some mechanisms for indirection, such as alternative table/column names and table inheritance. This may get you a long way, combined with using calculated properties on resources which depend on non-exposed properties that are mapped in EF Core. Perhaps some examples of what you're trying to achieve help to better understand your needs.

Adding a generic parameter to the service to query on a different data structure clashes with applying query string parameters, because they expect TResource to be applied on. And injecting such services sounds like a challenge, as the storage type is unknown to JADNC.

In any case, the repository and service interfaces are about to change substantially in #792, which provides stricter separation between service and repository by using an intermediate constraints model. The service contains no more usage of IQueryable, the repository only internally. This allows you to pick any storage format and/or technology, but it likely involves some work depending on what you're trying to achieve.

There's also some EF Core support in AutoMapper in case it helps.

@wasabii
Copy link
Author

wasabii commented Jul 29, 2020

Yeah. Okay. Removing the exposure of IQueryable outside of IResourceRepository would solve my issue, as it would let me do whatever I want in the repository to get the data.

I'm thinking about non-EF stuff... like CosmosDB, etc. Where the class used for querying the data source isn't the same shape as the resource being returned.

@bart-degreed
Copy link
Contributor

In case it helps. there's support in EF Core for CosmosDB.

Once #792 is merged, you should be able to implement your own repository and accept QueryLayer, which represents the request in an intermediate tree structure, free from a specific mapper technology. And then translate that to a data store of your choice, applying mappings as you see fit.

In the future I may be working on implementing parts of that to send queries to Elasticsearch instead of SQL.

Closing this out, as the question seems answered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants