reach4thelasers
reach4thelasers

Reputation: 26909

How to refactor a MongoDB .NET LINQ Query that uses a static method in a select statement

I've recently upgraded the .NET MongoDB Drivers from the Legacy ones to the newer ones. Lots of the queries don't work any more, this one has me stumped.

       var dataSource = permissions.Select(x => new PermissionSetPermissionGridViewModel
        {
            Id = x.Id,
            PermissionGroupInfo = new KeyValuePair<Guid?, string>(x.PermissionGroupId, TitleHelper.GetPermissionGroupTitle(x.PermissionGroupId)),
            IsEnabled = x.IsEnabled,
            ObjectType = ObjectTypeIds.GetEnumValue(x.ObjectTypeId.Value)
        }).ToList()

It doesn't seem to support the Static function TitleHelper.GetPermissionGroup() producing the following error.

    [NotSupportedException]: GetPermissionGroupTitle of type Saturn.WebUI.Core.Helpers.TitleHelper is not supported in the expression tree GetPermissionGroupTitle({document}{PermissionGroupId}).
   at MongoDB.Driver.Linq.Translators.AggregateLanguageTranslator.TranslateMethodCall(MethodCallExpression node)
   at MongoDB.Driver.Linq.Translators.AggregateLanguageTranslator.TranslateMapping(ProjectionMapping mapping)
   at MongoDB.Driver.Linq.Translators.AggregateLanguageTranslator.TranslateMapping(ProjectionMapping mapping)
   at MongoDB.Driver.Linq.Translators.AggregateLanguageTranslator.TranslateValue(Expression node)
   at MongoDB.Driver.Linq.Translators.QueryableTranslator.TranslateProjectValue(Expression selector)
   at MongoDB.Driver.Linq.Translators.QueryableTranslator.TranslateSelect(SelectExpression node)
   at MongoDB.Driver.Linq.Translators.QueryableTranslator.TranslatePipeline(PipelineExpression node)
   at MongoDB.Driver.Linq.Translators.QueryableTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
   at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Execute(Expression expression)
   at MongoDB.Driver.Linq.MongoQueryableImpl`2.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Saturn.WebUI.Areas.Security.Controllers.PermissionSetRecordController.GetStaticPermissions(DataSourceRequest request, Guid permissionSetId) in C:\work\saturn-develop\saturn\src\Saturn.WebUI\Areas\Security\Controllers\PermissionSetRecordController.cs:line 87

How can I refactor this query so that It is supported by the newer drivers?

Upvotes: 1

Views: 307

Answers (1)

Ventsislav Petrov
Ventsislav Petrov

Reputation: 101

Your GetPermissionGroupTitle(...) method cannot be translated to meaningful Mongo expression (it has no equivalent).

What you can do is to get all the needed data in memory and then subsequently invoke that static method. Basically, you should call .ToList() and then another .Select(...) in which to call your static method. Another way to do this is to use AutoMapper - we are calling such helper extension method when mapping between different models. Something like that should be the configuration:

CreateMap<Permission, PermissionSetPermissionGridViewModel>()
    .ForMember(
        dest => dest.PermissionGroupInfo,
        cfg => cfg.MapFrom(src => new KeyValuePair<Guid?, string>( TitleHelper.GetPermissionGroupTitle(src.PermissionGroupId, src.PermissionGroupId)))) 

Upvotes: 1

Related Questions