Code Monkey home page Code Monkey logo

Comments (9)

JanKotschenreuther avatar JanKotschenreuther commented on May 27, 2024 1

Actually we use ODataQueryOptions.Apply() to apply to an IQueryable<T> returned by IEnumerable<T>.AsQueryable() in case of §apply and aggregate cases.

The OData-Query-Options do not translate to SQL because the produced LINQ-Query does not work with EF Core (Were able to build those LINQ-Queries manually and run successfully but with OData did not work).

So as a workaround we call ToArray() to materialize the data and on the returning array we call AsQueryable() to apply the OData-Query-Options on the resulting IQueryable<T>.
That means you got to load the whole dataset into memory before applying the query.
But you can return a filtered dataset to the client.
Thats not perfect but at least you do not have to return the whole dataset.

Because you can apply to IQueryable<T> returned from IEnumerable<T>.AsQueryable() you can also apply to any Array/List nevermind where you pulled the data from.

The following Example shows a very specific case of ours, of course you could have loaded your array from anywhere else and using an ODataController instead of an generic ApiController.

Example:

	[ApiController]
	public class AggregateController<TEntity> : ControllerBase
        {
                private readonly MyContext _myContext;

		public AggregateController(MyContext myContext)
		{
			_myContext = myContext;
		}

		[HttpGet("")]
		public async Task<IActionResult> Aggregate(ODataQueryOptions<TEntity> queryOptions)
		{
			var dbSet = _myContext.Set<TEntity>();
                        var dataArray = dbSet.ToArray();

			IQueryable query = queryOptions.ApplyTo(dataArray().AsQueryable());

			return Ok(query);
		}
        }

from aspnetcoreodata.

tomasfabian avatar tomasfabian commented on May 27, 2024

Hi @jan-johansson-mr, to start the discussion, this is probably a question regarding to your data provider. Does it support the same IQueryable extension methods as for example Sql server providers does? If yes, than you are ready to go.
IMO OData.Net is data store agnostic.

from aspnetcoreodata.

tomasfabian avatar tomasfabian commented on May 27, 2024

Regarding to the sample, here I tried to approach a nosql MongoDb OData: https://github.com/tomasfabian/Joker/tree/master/Samples/MongoDb

I believe that in the result you have to accomplish the same CRUD operations.

from aspnetcoreodata.

jan-johansson-mr avatar jan-johansson-mr commented on May 27, 2024

Hi @tomasfabian,
Thanks for your provided sample.

My thoughts on OData is if we are able to use it, without being hard coupled to some DB provider. In essence, how do we, as developers, write an adapter that OData needs to access the data pool? If we can do that, then we can plug in any type of store for OData. E.g. in-memory store, or whatever we have in mind. I'm sure it is possible. The question is how we do it, and how much work is it to do?

And of course, is there a sample of some in-memory adapter (provider) for OData available?

from aspnetcoreodata.

xuzhg avatar xuzhg commented on May 27, 2024

@jan-johansson-mr I think the comments from @tomasfabian is correct. OData doesn't care about the Data source or data provider.

Your question " If we can do that, then we can plug in any type of store for OData. E.g. in-memory store", Can you share more detail about your thoughts?

from aspnetcoreodata.

jan-johansson-mr avatar jan-johansson-mr commented on May 27, 2024

Hi, Thanks for your reply. @tomasfabian is correct, however, my concern is not so much about plugging in one provider or another, my concern is if it is possible to plugin a provider that is not tied to some database, e.g. an in-memory store. My thoughts are that I want to resolve data through other means than query a database, e.g. memory or via some service. But also, in more advanced scenarios that some data may be pulled from services while others from memory. Or if I have a repository pattern on-top of some store, so I want OData to use my repository rather than direct store access. Is this possible?
Thanks

from aspnetcoreodata.

tomasfabian avatar tomasfabian commented on May 27, 2024

Hi @jan-johansson-mr,
I think that my answer still applies. OData does not care about the data source. You can inject your IRepository into your ODataController or into another service.
This example is for WebApi, but you can achieve the same with AspNetCore.OData.

For retrieving data you should return IQueryable<TEntity> from your repository in order to be able to use filtering etc., but this depends on your data provider. It is up to you whether you able or would like to support operators like Expand, Top etc. They can be disabled if you can't support these operators. But in these cases you should probably switch to AspNetCore WebApi. It also supports IAsyncEnumerable<T>. AFAIK OData does not support it.

Create, update and delete operations should be straightforward to implement even for in memory stores or you could redirect it to another web service.

So at the end you should be able to mix different data sources and they do not have to be some kind of database IMO.

@xuzhg let us know in case I'm not correct for some reasons. Thx

from aspnetcoreodata.

jan-johansson-mr avatar jan-johansson-mr commented on May 27, 2024

Thanks @JanKotschenreuther, it's a nice trick, and I do share your reflections on up and downsides to the trick. My concern with OData is that it is a kind of black box "SQL" on HTTP. OData does not delegate how to resolve data (GraphQL does) but "owns" the data to filter and aggregate. Therefore OData needs all access to all data to do the work (with some provider as EF, or as in your case a neat trick with some ups and downs). And to implement a provider as EF takes years. As I recall reading that such a provider basically dwarf almost any application by leaps and bounds in complexity. My original question was that if OData was able to delegate how to resolve data and if so how that was done and if there were some examples of that.

from aspnetcoreodata.

tomasfabian avatar tomasfabian commented on May 27, 2024

Hi @jan-johansson-mr,
OData basically translates HTTP requests to an AST and then to SQL or MQL for unstructured data, etc., with some kind of provider as you've already mentioned. These providers are using the aforementioned IQueryable<T> interface. This interface has a lot of extension methods and an expression visitor is used to generate a string (URL. SQL) query from them. The same magic is used on the client side if you are using OData client (DataServiceContext). So my point is that there is only one http request or one provider (EF core) query at the end (of course can depend on the internal implementation).

If I understand you correctly you would like to combine the end result of an OData query from different data sources. OData AFAIK doesn't have a similar concept to GraphQL's resolvers.

On the other hand I think that with OData you probably don't have to solve the n+1 problem, because it will generate a JOIN clause from $Expands, etc. In GraphQL you have to implement some kind of batch Data Loader in order to achieve this. In most cases a Data loader only moves this issue from clients to the server (it depends on the implementation).

So I don't think that it is possible to easily (out of the box) combine a result from e.g. MongoDb, Redis, REST API or SQL server, etc. with ONE OData query.

Do you agree @xuzhg?

from aspnetcoreodata.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.