.NET 4.6 Enum in where expression

2 posts, 0 answers
  1. Marianna
    Marianna avatar
    2 posts
    Member since:
    Jul 2014

    Posted 23 Jul 2015 Link to this post

    Hi,

    It seems updating from .NET 4.5 to 4.6 causes trouble filtering on Enum entity member. We have tried with Data Access 2015 Q1 and Q2 too.
    Whether is it related to Data Access or .NET Framework?

      

    // works under .NET Framework 4.5, but fails under .NET Framework 4.6
    return Clients.Where(w => (w.ClientType & ClientTypeEnum.Client) == ClientTypeEnum.Client);
    // ​modified code now works under .NET Framework 4.6 too
    return Clients.Where(w => w.ClientType == ClientTypeEnum.Client || w.ClientType == ClientTypeEnum.Both);
     
      
    [Flags]
    public enum ClientTypeEnum
    {
        Client = 0x1,
        Vendor = 0x2,
        Both = Client | Vendor
    }

     

    Exception:

    System.InvalidOperationException was unhandled by user code
      HResult=-2146233079
      Message=An exception occurred during the execution of 'Extent<WebInvoice.DAL.Schema.CompaniesOfBusinessEntity>().Where(w => (w.BusinessGroupEntity == value(WebInvoice.Core.Services.ClientService)._userService.BusinessGroup)).Select(s => s).Where(w => (Convert(Convert((Convert(w.ClientType) & Convert(Client)))) == Convert(Client))).OrderBy(cob => cob.Name)'. Failure: Must specify parameter on right side of operation. ({3})
    See InnerException for more details.
    Complete Expression:
    .Call System.Linq.Queryable.OrderBy(
        .Call System.Linq.Queryable.Where(
            .Call System.Linq.Queryable.Select(
                .Call System.Linq.Queryable.Where(
                    .Constant<Telerik.OpenAccess.Query.ExtentQueryImpl`1[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity]>(Extent<WebInvoice.DAL.Schema.CompaniesOfBusinessEntity>()),
                    '(.Lambda #Lambda1<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,System.Boolean]>)),
                '(.Lambda #Lambda2<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,WebInvoice.DAL.Schema.CompaniesOfBusinessEntity]>))
            ,
            '(.Lambda #Lambda3<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,System.Boolean]>)),
        '(.Lambda #Lambda4<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,System.String]>))
     
    .Lambda #Lambda1<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,System.Boolean]>(WebInvoice.DAL.Schema.CompaniesOfBusinessEntity $w)
    {
        $w.BusinessGroupEntity == (.Constant<WebInvoice.Core.Services.ClientService>(WebInvoice.Core.Services.ClientService)._userService).BusinessGroup
    }
     
    .Lambda #Lambda2<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,WebInvoice.DAL.Schema.CompaniesOfBusinessEntity]>(WebInvoice.DAL.Schema.CompaniesOfBusinessEntity $s)
    {
        $s
    }
     
    .Lambda #Lambda3<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,System.Boolean]>(WebInvoice.DAL.Schema.CompaniesOfBusinessEntity $w)
    {
        (System.Int32)((WebInvoice.DAL.Enum.ClientTypeEnum)((System.Int32)$w.ClientType & (System.Int32).Constant<WebInvoice.DAL.Enum.ClientTypeEnum>(Client))) ==
        (System.Int32).Constant<WebInvoice.DAL.Enum.ClientTypeEnum>(Client)
    }
     
    .Lambda #Lambda4<System.Func`2[WebInvoice.DAL.Schema.CompaniesOfBusinessEntity,System.String]>(WebInvoice.DAL.Schema.CompaniesOfBusinessEntity $cob)
    {
        $cob.Name
    }
     
      Source=Telerik.OpenAccess.35.Extensions
      StackTrace:
           at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQuery(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid)
           at Telerik.OpenAccess.Query.ExpressionExecution.PerformDatabaseQueryMulti[T](Expression expr, ExecutionSettings settings, Object[] grpVals, Boolean checkOid, QueryOptions options)
           at Telerik.OpenAccess.Query.Piece`1.ExecuteMultiple()
           at Telerik.OpenAccess.Query.Piece`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
           at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
           at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
           at WebInvoice.Core.Services.InvoiceService.FillDataModelsForSave(DataModels m) in E:\Repository\1ClickBusiness\branches\3.2.1\WebInvoice.Core\Services\InvoiceService.cs:line 1171
           at WebInvoice.Areas.Members.Controllers.InvoiceController.Save(Nullable`1 id, Nullable`1 companyId, Nullable`1 page, IClientService clientService) in E:\Repository\1ClickBusiness\branches\3.2.1\WebInvoice\Areas\Members\Controllers\InvoiceController.cs:line 410
           at lambda_method(Closure , ControllerBase , Object[] )
           at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
           at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
           at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
           at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod()
           at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
           at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
           at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
           at System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult, Object tag)
           at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
           at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
           at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
      InnerException:
           CanRetry=true
           HResult=-2146233088
           Message=Must specify parameter on right side of operation. ({3})
           Source=Telerik.OpenAccess.35.Extensions
           StackTrace:
                at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQueryImpl(Type resultType, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid)
                at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQuery(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid)

  2. Thomas
    Admin
    Thomas avatar
    590 posts

    Posted 27 Jul 2015 Link to this post

    Hello Marianna,

    yikes! You've found an issue : With the VS2015 Roslyn compiler, Enum values are written symbolically into the LINQ expression tree; before that, their numeric value was used. Therefore, we seem to lack the resolution for those constant values.

    Example:
    .... .Where(x => (x.MyEnum & ConsoleModifiers.Shift) == ConsoleModifiers.Shift)...

    VS2013 produced:
    .Lambda #Lambda1<System.Func`2[EnumLinqApp.Product,System.Boolean]>(EnumLinqApp.Product $x)
    {
                (System.Int32)((System.ConsoleModifiers)((System.Int32)$x.MyEnum & 2)) == 2
    }

    VS2015 produced:
     .Lambda #Lambda1<System.Func`2[EnumLinqApp.Product,System.Boolean]>(EnumLinqApp.Product $x) {
                (System.Int32)((System.ConsoleModifiers)((System.Int32)$x.MyEnum & (System.Int32).Constant<System.ConsoleModifiers>(Shift))) ==
                (System.Int32).Constant<System.ConsoleModifiers>(Shift)
     }

    I think a fix should not be hard to produce for this, yet I cannot give you a date when it will be done. Meanwhile, you could (at least for your small example) use the workaround that you described earlier.

    Thanks for reporting this issue! I've filed a bug for this (#240464)

    Regards,
    Thomas
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
  3. DevCraft banner
Back to Top