DevExpress / DevExtreme.AspNet.Data

DevExtreme data layer extension for ASP.NET
MIT License
154 stars 128 forks source link

Provide additional parameters to support provision of execution context to Load and LoadAsync #588

Open statler opened 1 year ago

statler commented 1 year ago

Hi Aleksey

Statler here - you may remember me from such posts as

So, just when I thought I had every base covered, I have come across a new use case that I need to manage. I am hoping you can help me out here.

My case deals successfully with automapper projection by:

  1. Registering CustomAccessors automatically from the automapper config (https://github.com/DevExpress/DevExtreme.AspNet.Data/issues/367)
  2. Getting the IDs of all results from the Devexpress.AspNet.data expression compilation query
  3. Querying the base type for all ids in (2), and using ProjectTo

This all works really well for ProjectTo(Mapconfig)

Where I have come unstuck is the overload of ProjectTo(Mapconfig, MapParameter) (https://docs.automapper.org/en/stable/Queryable-Extensions.html#parameterization)

This enables the injection of runtime variables into the projection and is a case I can't see a way to resolve as it is not possible to provide context in the CustomAccessors or CustomFilters. Would you be open to modifying the signatures for these methods to support the provision of context via an additional parameter to DataSourceLoader.LoadAsync / DataSourceLoader.Load

statler commented 1 year ago

I have just put together a PR (https://github.com/DevExpress/DevExtreme.AspNet.Data/pull/589) that shows what I am thinking. You would have different thoughts on how it should be done, but the solution works and shows the principle.

The main thing this PR does is:

As I started out, I expect you may want to refactor the exact way this is done, but do you see the utility and would you be willing to implement in the root library?

Here is an example of it in use (real world). This method:

Subsequently the operator is projected to a DTO, which is achieved using the same object passed in the runtimecontext - but that's part of my other library.

        CustomFilterCompilers.RegisterBinaryExpressionCompilerWithContext((info, rtContext) =>
        {
            if (info.DataItemExpression.Type == typeof(Notification))
            {
                if (info.AccessorText == "DateDismissed")
                {
                    dynamic dynObj = new DynamicWrapper(rtContext.RuntimeResolutionContext);
                    if (int.TryParse(dynObj.UserId.ToString(), out int _ui))
                    {
                        var pBaseExp = info.DataItemExpression as ParameterExpression;
                        var pBaseProperty = Expression.PropertyOrField(pBaseExp, "NotificationTos");

                        var _p = Expression.Parameter(typeof(NotificationTo), "nTo");
                        var baseResult = rtContext.CompileNonCustomBinary(_p, GetParametersAsList(info));
                        var predicate = PredicateBuilder.New(Expression.Lambda<Func<NotificationTo, bool>>(baseResult, _p));
                        predicate.And((p) => p.UserId == _ui);

                        var result = Expression.Call(
                            typeof(Enumerable), "Any", new[] { _p.Type },
                            pBaseProperty, predicate);

                        var ex22 =  Expression.Lambda(result, pBaseExp) as Expression<Func<Notification, bool>>;
                        return CompileWhereExpression(info, ex22).Body;
                    }
                }
            }
            return null;
        });

`

statler commented 1 year ago

OK - so I have expanded the scope of this somewhat. I have finally gotten around to implementing a non-intrusive integration of Automapper. PR is at https://github.com/DevExpress/DevExtreme.AspNet.Data/pull/589.

The PR is mainly to start a discussion about what (if any) you want in the main library.

Anyone wanting an automapper-ready implementation in the meantime can pull https://github.com/statler/DevExtreme.AspNet.Data

I will have a nuget up shortly

statler commented 1 year ago

OK - nuget package is available.

Available as nuget at https://www.nuget.org/packages/DXAutomap.AspNet.Data/1.12.0

NuGet\Install-Package DXAutomap.AspNet.Data -Version 1.12.0