AutoMapper / AutoMapper.Extensions.ExpressionMapping

MIT License
144 stars 39 forks source link

Cosmos DB LINQ provider with Odata sans EF #155

Closed wbuck closed 1 year ago

wbuck commented 1 year ago

Hi Blaise,

So, for the last couple of weeks I've been trying to use the Cosmos DB LINQ provider with Odata. I'm not using EF as it's generating incorrect SQL.

Anyway, some issues I've run into for example is that $select does not work (full stop). I had to completely replace the MethodCallExpression representing the Select method call and generate a new runtime type in order to get that working.

Next, I created an Expression tree visitor which replaces all Expression<TSource> to Expression<TDest> expressions using AutoMapper for type mappings.

All works well, but I know that you have this repo as well this repo and I'm wondering if I'm just reinventing the wheel here.

Questions

  1. Does this library depend on EF in anyway (think extension methods)?
  2. Can I map an entire expression tree?

For example:

 // Think of the expression tree generated from OData's ODataQueryOptions.ApplyTo method.
 sourceQuery = sourceQuery.Where(...).Select(...).OrderBy(...);
 var expression =  mapper.MapExpression<Source, Destination>(sourceQuery.Expression);

Granted, in the above example, I don't think that would work unless you also had a destination IQueryable to work with.

What I'm thinking of is to first apply the Odata query to the CosmosEnumerable, pass the Expression to the mapper.MapExpression and then use my SelectReplacer to replace the invalid Select MethodCallExpression with a valid one.

Or maybe I can use this library within my Expression visitor to map any Expression<TSource> to Expression<TDest.

I'm just not 100% sure on how this library is supposed to be used.

BlaiseD commented 1 year ago

The other library was started because of questions about using this one with OData.

I would use the code here and here as a guide.

I'm pretty sure none of that is EF specific. It's creating the selections and expansions from ODataQueryOptions. I would test that against Cosmos DB and go from there. The EF6 and EF Core libraries share much of the same code - maybe a third project targeting Cosmos DB might be in order if that makes sense for you.

wbuck commented 1 year ago

@BlaiseD Now are you talking about a third project in this repo? So, something like AutoMapper.AspNetCore.OData.CosmosDb?

That would be nice but there are differences between how queries are executed asynchronously between EF and the Cosmos LINQ provider (which may require exposing CosmosDB specific stuff in the public facing API).

Also, some Odata options may not make sense with a NoSQL DB (expansions for example as there are no joins except for inner joins which could be translated to SelectMany I guess).

BlaiseD commented 1 year ago

Yes - that is what I meant - a similar project in the repo. I don't know the details. If you're getting data from the query and translating the data into LINQ expressions then I'd assume it's possible to match the given provider e.g. the Get method uses includes as opposed to expansions. Or maybe what you already have is the best option - depends on what you find.

wbuck commented 1 year ago

@BlaiseD I'm going to make a feature request on the other repo. I'll start working on this (most of it is already done but I want to utilize a lot of the helpers already defined in both this repo and the other).

BlaiseD commented 1 year ago

Feature request: Add support for CosmosDB