This is a migrated thread and some comments may be shown as answers.

.NET 4.6 Enum in where expression

1 Answer 115 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Marianna
Top achievements
Rank 1
Marianna asked on 23 Jul 2015, 02:06 PM

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)

1 Answer, 1 is accepted

Sort by
0
Thomas
Telerik team
answered on 27 Jul 2015, 03:29 PM
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.
Tags
General Discussions
Asked by
Marianna
Top achievements
Rank 1
Answers by
Thomas
Telerik team
Share this question
or