New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Protocol] Int64 could not be used as key #123

Closed
karataliu opened this Issue Jul 20, 2015 · 9 comments

Comments

Projects
None yet
5 participants
@karataliu
Contributor

karataliu commented Jul 20, 2015

metadata:

<EntityType Name="Person"><Key><PropertyRef Name="PersonId"/></Key><Property Name="PersonId" Type="Edm.Int64" Nullable="false"><Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/></Property><Property Name="UserName" Type="Edm.String" MaxLength="max"/><Property Name="FirstName" Type="Edm.String" Nullable="false" MaxLength="max"/><Property Name="LastName" Type="Edm.String" MaxLength="26"/><Property Name="Concurrency" Type="Edm.Int64" Nullable="false"/><NavigationProperty Name="Friends" Type="Collection(Microsoft.Restier.WebApi.Test.Services.Trippin.Models.Person)"/><NavigationProperty Name="Trips" Type="Collection(Microsoft.Restier.WebApi.Test.Services.Trippin.Models.Trip)"/></EntityType>
http://localhost:18384/api/TripPin/People%280%29/

Response:

HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; odata.metadata=minimal
Expires: -1
Server: Microsoft-IIS/8.0
OData-Version: 4.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcZ2l0XHRcUkVTVGllclx0ZXN0XE9EYXRhRW5kVG9FbmRUZXN0c1xNaWNyb3NvZnQuUmVzdGllci5XZWJBcGkuVGVzdC5TZXJ2aWNlcy5UcmlwcGluXGFwaVxUcmlwUGluXFBlb3BsZSgwKVw=?=
X-Powered-By: ASP.NET
Date: Mon, 20 Jul 2015 08:39:23 GMT
Content-Length: 3466

{
  "error":{
    "code":"","message":"An error has occurred.","innererror":{
      "message":"The binary operator Equal is not defined for the types 'System.Int64' and 'System.Int32'.","type":"System.InvalidOperationException","stacktrace":"   at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)\r\n   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)\r\n   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right)\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.CreateEqualsExpression(ParameterExpression parameterExpression, String propertyName, Object propertyValue) in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 383\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.ApplyKeys(IQueryable queryable, KeyValuePathSegment keySegment, IEdmEntityType entityType, Type type) in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 313\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.GetQuery(HttpRequestMessageProperties odataProperties) in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 510\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.<Get>d__0.MoveNext() in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 126\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
    }
  }
}

@karataliu karataliu added the SpecBash label Jul 20, 2015

@karataliu

This comment has been minimized.

Contributor

karataliu commented Jul 20, 2015

Also not work for Int16:

{
  "error":{
    "code":"","message":"An error has occurred.","innererror":{
      "message":"The binary operator Equal is not defined for the types 'System.Int16' and 'System.Int32'.","type":"System.InvalidOperationException","stacktrace":"   at System.Linq.Expressions.Expression.GetEqualityComparisonOperator(ExpressionType binaryType, String opName, Expression left, Expression right, Boolean liftToNull)\r\n   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)\r\n   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right)\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.CreateEqualsExpression(ParameterExpression parameterExpression, String propertyName, Object propertyValue) in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 383\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.ApplyKeys(IQueryable queryable, KeyValuePathSegment keySegment, IEdmEntityType entityType, Type type) in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 313\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.GetQuery(HttpRequestMessageProperties odataProperties) in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 510\r\n   at Microsoft.Restier.WebApi.ODataDomainController`1.<Get>d__0.MoveNext() in d:\\git\\t\\RESTier\\src\\Microsoft.Restier.WebApi\\ODataDomainController.cs:line 126\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
    }
  }
}

@karataliu karataliu changed the title from [Protocol] Int64 could not be key to [Protocol] Int64 could not be used as key Jul 21, 2015

@karataliu

This comment has been minimized.

Contributor

karataliu commented Jul 30, 2015

Related odatalib issue: OData/odata.net#175

@karataliu karataliu added this to the v0.4 or later milestone Jul 30, 2015

@lewischeng-ms lewischeng-ms added the bug label Oct 26, 2015

@lewischeng-ms lewischeng-ms added 1 - Backlog and removed SpecBash labels Nov 5, 2015

@lewischeng-ms lewischeng-ms modified the milestones: 0.5 or later, 0.4.0 Nov 5, 2015

@SaucyJack

This comment has been minimized.

SaucyJack commented Feb 17, 2016

Perhaps this is naive, but I solved this problem by changing the construction of the constant in the CreateEqualsExpression method in RestierQueryBuilder so that it converts the property value to the type of the property:

private static BinaryExpression CreateEqualsExpression(
    ParameterExpression parameterExpression, 
    string propertyName,
    object propertyValue)
{
    var property = Expression.Property(parameterExpression, propertyName);
    var constant = Expression.Constant(Convert.ChangeType(propertyValue, property.Type), property.Type);
    return Expression.Equal(property, constant);
}
@lewischeng-ms

This comment has been minimized.

Contributor

lewischeng-ms commented Feb 18, 2016

@SaucyJack Nice solution! Looks good to me. Just one suggestion: can we ignore the second property.Type? And would you please send a pull request to us for a quick fix? Thanks!

@SaucyJack

This comment has been minimized.

SaucyJack commented Feb 18, 2016

@lewischeng-ms Ah, I didn't see that there was an overload of Expression.Constant that didn't require the type (why would it require the type anyway, right?). I'll submit a pull request. RESTier is providing me with exactly the solution I need for our API so I'm very excited to use and contribute where I'm able.

@lewischeng-ms

This comment has been minimized.

Contributor

lewischeng-ms commented Mar 16, 2016

Already done by #294

@cilerler

This comment has been minimized.

Contributor

cilerler commented Apr 26, 2016

@SaucyJack unfortunately PUT still throws an error where PATCH, POST, DELETE, GET works just fine.

{
  "error": {
    "code": "",
    "message": "An error has occurred.",
    "innererror": {
      "message": "Unsupported type for property: ID.",
      "type": "System.NotSupportedException",
      "stacktrace": "   at Microsoft.Restier.EntityFramework.Submit.ChangeSetPreparer.SetValues(Object instance, Type type, IReadOnlyDictionary`2 values)\r\n   at Microsoft.Restier.EntityFramework.Submit.ChangeSetPreparer.SetValues(DbEntityEntry dbEntry, DataModificationEntry entry, Type entityType)\r\n   at Microsoft.Restier.EntityFramework.Submit.ChangeSetPreparer.<PrepareAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n   at Microsoft.Restier.Core.Submit.DefaultSubmitHandler.<SubmitAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at Microsoft.Restier.Core.ApiContextExtensions.<SubmitAsync>d__f.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at Microsoft.Restier.WebApi.RestierController.<Update>d__2a.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at Microsoft.Restier.WebApi.RestierController.<Put>d__12.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
    }
  }
}
@chinadragon0515

This comment has been minimized.

Contributor

chinadragon0515 commented Apr 27, 2016

@cilerler we always not take a look at closed issues unless someone check the mail notification and see comments, can you open a new issue if you have some issues, I do not want to reopen a closed issue, thanks.

@cilerler

This comment has been minimized.

Contributor

cilerler commented Apr 27, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment