Skip to content
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
Closed

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

karataliu opened this issue Jul 20, 2015 · 9 comments
Assignees
Labels
Milestone

Comments

@karataliu
Copy link
Contributor

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
Copy link
Contributor Author

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 [Protocol] Int64 could not be key [Protocol] Int64 could not be used as key Jul 21, 2015
@karataliu
Copy link
Contributor Author

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 modified the milestones: 0.5 or later, 0.4.0 Nov 5, 2015
@SaucyJack
Copy link

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
Copy link
Contributor

@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
Copy link

@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
Copy link
Contributor

Already done by #294

@cilerler
Copy link
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
Copy link
Contributor

@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
Copy link
Contributor

@chinadragon0515 done #380

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants