1
votes

I have an OData service. In the table in my MS.SQLServer there is no primary key and it has a field that its name is Id and it is smallint. I generated a controller in my OData service and it has two get actions as below :

    // GET: odata/BankAccs
    [Queryable]
    public IQueryable<BankAcc> Get()
    {
        return db.BankAcc;
    }

    // GET: odata/BankAccs(5)
    [Queryable]
    public SingleResult<BankAcc> Get([FromODataUri] short key)
    {
        return SingleResult.Create(db.BankAcc.Where(bankAcc => bankAcc.Id 
           == key));
    }

I installed OData v4 Client Code Generator in my client side to call this service. I call the service with below code :

    var bankAccs = container.BankAccs.Where(n => n.Id == 312).Select(x => 
                                      x).ToList();
    var bankAcc = bankAccs.Select(x => x.No).ToList();
    Console.WriteLine(bankAcc[0]);

When I run my client then I will encounter below error :

Microsoft.OData.Client.DataServiceQueryException: 'An error occurred while processing this request.'

Inner Exception DataServiceClientException: {"error":{"code":"","message":"An error has occurred.","innererror":{"message":"Unknown function 'cast'.","type":"System.NotImplementedException","stacktrace":" at System.Web.Http.OData.Query.Expressions.FilterBinder.BindSingleValueFunctionCallNode(SingleValueFunctionCallNode node)\r\n at System.Web.Http.OData.Query.Expressions.FilterBinder.Bind(QueryNode node)\r\n at System.Web.Http.OData.Query.Expressions.FilterBinder.BindBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode)\r\n at System.Web.Http.OData.Query.Expressions.FilterBinder.Bind(QueryNode node)\r\n at System.Web.Http.OData.Query.Expressions.FilterBinder.BindExpression(SingleValueNode expression, RangeVariable rangeVariable, Type elementType)\r\n at System.Web.Http.OData.Query.Expressions.FilterBinder.Bind(FilterClause filterClause, Type filterType, IEdmModel model, IAssembliesResolver assembliesResolver, ODataQuerySettings querySettings)\r\n at System.Web.Http.OData.Query.FilterQueryOption.ApplyTo(IQueryable query, ODataQuerySettings querySettings, IAssembliesResolver assembliesResolver)\r\n at System.Web.Http.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings)\r\n at System.Web.Http.OData.EnableQueryAttribute.ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)\r\n at System.Web.Http.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n at System.Web.Http.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)\r\n at System.Web.Http.Filters.ActionFilterAttribute.OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)\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.Filters.ActionFilterAttribute.d__6.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.Filters.ActionFilterAttribute.d__5.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.d__5.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.d__15.MoveNext()"}}}

I know that the problem is for this smallint in my database and I cannot change it and how can I solve it in my program???

1
The SQL Server smallint type is equivalent to .net Int16 and c# short. How is the property BankAcc.Id declared? Is it Int16/short or is other type? - Cleptus
Yes, It is exactly Int16 and short. As you see in the input of second Get action that scaffolding made is 'short' - Mostafa
I searched it and found the answer in the address ===>> (forums.asp.net/t/1973366.aspx?odata+unknown+function+cast) In this address said that I must write (var bankAccs = container.BankAccs.Where(n => n.Id..Equals(312)).Select(x => x).ToList();) instead of (var bankAccs = container.BankAccs.Where(n => n.Id == 312).Select(x => x).ToList();) in my client side application. - Mostafa
Consider answering your own question, it is not only allowed but encouraged. - Cleptus
Thank you. It solved my problem. Do you have any better idea?? - Mostafa

1 Answers

0
votes

Your client application is most likely not providing a short but an int to the OData layer, raising the error.

You can workaround it querying the data using:

var bankAccs = container.BankAccs.Where(n => n.Id..Equals(312)).Select(x => x).ToList();

instead of:

var bankAccs = container.BankAccs.Where(n => n.Id == 312).Select(x => x).ToList();

Source of that info: odata unknown function cast

I would give a try avoiding the wrong type explicitly:

short bankId = 312;
var bankAccs = container.BankAccs.Where(n => n.Id == (short)bankId).Select(x => x).ToList();