Closed a-elnajjar closed 5 years ago
Hi @a-elnajjar ,
As you could see from the stack trace, exception is thrown from EntityFrameworkCore
when it tried to build the query. OData supports nullable types pretty fine, so I suspect that you have conversion issue in your EF entities. For example, if your column is type of bit
then, you might get such error as -1 could not be converted to boolean.
If you could provide more details, perhaps I could help you.
public class Client : BaseEntity
{
public Client()
{
Assessments = new HashSet
public class Assessment : BaseEntity
{
public Assessment(){}
public Guid Id { get; set; }
public int? Status { get; set; }
public int AssessmentNumber { get; set; }
public virtual Language Language { get; set; }
public virtual AssessmentType AssessmentType { get; set; }
public User User { get; set; }
public Guid? ClientId { get; set; }
public virtual Client Client { get; set; }
public String ClientName { get; set; }
public DateTime? AssessmentDate { get; set; }
public virtual Catalog Catalog { get; set; }
public string CatalogId { get; set; }
public virtual Rater Rater { get; set; }
public virtual AssessmentData AssessmentData { get; set; }
public virtual AssessmentResume AssessmentResume { get; set; }
public virtual AssessmentScoreHistory AssessmentScoreHistory { get; set; }
public string JSONData { get; set; }
//Ignore in Database
public Client GetClient { get; set; }
} from DbContaxt //client modelBuilder.Entity().ToTable("Clients"); modelBuilder.Entity().HasKey(x => x.Id); modelBuilder.Entity().Property(x => x.Id).ForSqlServerHasDefaultValueSql("newid()"); //<-- this line should create new Guid in insert modelBuilder.Entity().Ignore(x => x.DisplayName); modelBuilder.Entity().Ignore(x => x.DisplayAgeInfo); modelBuilder.Entity().Property(x => x.FirstName).HasMaxLength(50); modelBuilder.Entity().Property(x => x.LastName).HasMaxLength(50); modelBuilder.Entity().Property(x => x.ParticipantId).HasMaxLength(50); modelBuilder.Entity().Property(x => x.Email).HasMaxLength(100); modelBuilder.Entity().HasOne(x => x.DefaultLanguage).WithMany(x => x.Clients).HasForeignKey("DefaultLanguageId"); modelBuilder.Entity().HasOne(x => x.User).WithMany(x => x.Clients).HasForeignKey("UserId"); modelBuilder.Entity().HasMany(c => c.ClientTags).WithOne(c => c.Client).HasForeignKey("ClientId"); modelBuilder.Entity().HasMany(c => c.Assessments).WithOne(c => c.Client).HasForeignKey("ClientId"); //2-Assessment modelBuilder.Entity().ToTable("Assessments"); modelBuilder.Entity().HasKey(x => x.Id); modelBuilder.Entity().Property(x => x.Id).ForSqlServerHasDefaultValueSql("newid()"); modelBuilder.Entity().Property(x => x.AssessmentNumber).ValueGeneratedOnAdd(); modelBuilder.Entity().Ignore(x => x.GetClient); modelBuilder.Entity().Property(x => x.JSONData); modelBuilder.Entity().Property(x => x.AssessmentDate).HasColumnType("datetime"); modelBuilder.Entity().HasOne(x => x.Language).WithMany(x => x.Assessments).HasForeignKey("LanguageId"); modelBuilder.Entity().HasOne(x => x.AssessmentData).WithOne(x => x.Assessment).HasForeignKey(x => x.Id); modelBuilder.Entity().HasOne(x => x.AssessmentResume).WithOne(x => x.Assessment).HasForeignKey(x => x.Id); modelBuilder.Entity().HasOne(x => x.AssessmentScoreHistory).WithOne(x => x.Assessment).HasForeignKey(x => x.Id); modelBuilder.Entity().HasOne(x => x.Catalog).WithMany(x => x.Assessments).HasForeignKey("CatalogId"); modelBuilder.Entity().HasOne(x => x.User).WithMany(x => x.Assessments).HasForeignKey("UserId"); modelBuilder.Entity().HasOne(x => x.Client).WithMany(x => x.Assessments).HasForeignKey("ClientId"); ApplyJsonPropertyConfig(modelBuilder);
Assessments DML [Id] [uniqueidentifier] NOT NULL, [Status] [int] NULL, [AssessmentNumber] [int] IDENTITY(1,1) NOT NULL, [ClientId] [uniqueidentifier] NULL, [ClientName] nvarchar NULL, [AssessmentDate] [datetime] NULL, [JSONData] nvarchar NULL, [CreatedDate] [datetime] NOT NULL, [UpdatedDate] [datetime] NULL, [DeletedDate] [datetime] NULL, [IsDeleted] [bit] NOT NULL, [AssessmentTypeId] [uniqueidentifier] NULL, [CatalogId] nvarchar NULL, [LanguageId] [int] NULL, [UserId] [uniqueidentifier] NULL, CONSTRAINT [PK_dbo.Assessments] PRIMARY KEY CLUSTERED Clients DML [Id] [uniqueidentifier] NOT NULL, [FirstName] nvarchar NULL, [LastName] nvarchar NULL, [Email] nvarchar NULL, [ParticipantId] nvarchar NULL, [BirthDate] [datetime] NULL, [Gender] [int] NOT NULL, [Age] [tinyint] NULL, [Status] [int] NOT NULL, [Notes] nvarchar NULL, [CreatedDate] [datetime] NOT NULL, [UpdatedDate] [datetime] NULL, [DeletedDate] [datetime] NULL, [IsDeleted] [bit] NOT NULL, [DefaultLanguageId] [int] NULL, [UserId] [uniqueidentifier] NOT NULL, CONSTRAINT [PK_dbo.Clients] PRIMARY KEY CLUSTERED
we are using Entity framework core1.2.1, Microsoft.AspNet.OData 6.0.0 Microsoft.OData.Core 7.3.1 Microsoft.OData.Edm 7.3.1
same problem here, using odata3, i think this is an odata issue, would be great if you could assist :-)
Stracktrace
Exception has been thrown by the target of an invocation.","type":"System.Reflection.TargetInvocationException","stacktrace":" at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Web.Http.OData.ExpressionHelpers.Count(IQueryable query, Type type)
at System.Web.Http.OData.Query.InlineCountQueryOption.GetEntityCount(IQueryable query)
at System.Web.Http.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings)
at System.Web.Http.OData.EnableQueryAttribute.ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
at System.Web.Http.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)
at System.Web.Http.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
at System.Web.Http.Filters.ActionFilterAttribute.OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()","internalexception":{
"message":"The binary operator AndAlso is not defined for the types 'System.Boolean' and 'System.Nullable`1[System.Boolean]'.","type":"System.InvalidOperationException","stacktrace":" at System.Linq.Expressions.Expression.AndAlso(Expression left, Expression right, MethodInfo method)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at Remotion.Linq.Parsing.ThrowingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.ProcessComparisonExpression(BinaryExpression binaryExpression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at Remotion.Linq.Parsing.ThrowingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, INodeTypeProvider nodeTypeProvider, IDatabase database, IDiagnosticsLogger`1 logger, Type contextType)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.LongCount[TSource](IQueryable`1 source)"
}
URL Called (decoded)
http://localhost:9002/odata/Products?$filter=(ProjectId eq guid'e4b44742-0cf7-479d-be41-054603b3d6cc') and (ProductListId eq guid'9e6110e1-a8bf-48a0-9ff6-b53a68e7a292')&$orderby=Name&$top=15&$inlinecount=allpages
Relevant Properties
public class Product ... {
public Guid? ProjectId { get;set; }
public Guid ProductListId { get;set; }
}
looks like the this the nullable ProjectId check results in a nullable boolean, instead of the expected false for all null values. Removing the ProjectId Filter from the URL solves the problem, but that of course is not an option ;)
the same code using entity framework core directly works as expected:
public class ProductsController : ODataController{
[HttpGet]
[EnableQuery]
[Authorize]
public IHttpActionResult Get() {
var projectId = Guid.Parse("e4b44742-0cf7-479d-be41-054603b3d6cc");
var productListId = Guid.Parse("9e6110e1-a8bf-48a0-9ff6-b53a68e7a292");
var db = new AppDbContext();
return Ok(db.Products.Where(i => i.ProjectId == projectId && i.ProductListId == productListId));
}
}
I am trying to set odata URL $filter, but I have some problem with and "Status eq -1" not working because Status property is nullable integer int? in Assessment Class I have this exception the url
localhost/Assessments?$expand=Client&$filter=CatalogId%20eq%20'PVAT'%20and%20Status%20eq%20-1&$select=FirstName%2CLastName { "error": { "code": "", "message": "An error has occurred.", "innererror": { "message": "The binary operator AndAlso is not defined for the types 'System.Nullabled49.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.Owin.HttpMessageHandlerAdapter.d 13.MoveNext()"
}
}
}
1[System.Boolean]' and 'System.Boolean'.", "type": "System.InvalidOperationException", "stacktrace": " at System.Linq.Expressions.Expression.AndAlso(Expression left, Expression right, MethodInfo method)\r\n at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression)\r\n at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)\r\n at Remotion.Linq.Parsing.ThrowingExpressionVisitor.Visit(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.ProcessComparisonExpression(BinaryExpression binaryExpression)\r\n at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression expression)\r\n at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)\r\n at Remotion.Linq.Parsing.ThrowingExpressionVisitor.Visit(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)\r\n at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)\r\n at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection
1 bodyClauses, QueryModel queryModel)\r\n at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)\r\n at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryModelVisitor.VisitQueryModel(QueryModel queryModel)\r\n at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)\r\n at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, INodeTypeProvider nodeTypeProvider, IDatabase database, ILogger logger, Type contextType)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass19_01.<CompileQuery>b__0()\r\n at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func
1 compiler)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQuery[TResult](Expression query)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)\r\n at Remotion.Linq.QueryableBase
1.System.Collections.IEnumerable.GetEnumerator()\r\n at System.Web.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, 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.Net.Http.HttpContent.