[CSHARP-483] Error MongoDB.Driver.Linq.SelectQuery.BuildQuery Created: 31/May/12  Updated: 20/Mar/14  Resolved: 31/May/12

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 1.4.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Nikolay Chistyakov Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: driver
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

my code:

IQueryable<MessageOutbound> query = from mo in this.All() where !mo.IsSending && mo.RemainingRetryCount > 0 select mo;
 
query = query.Where(mo => mo.DateLastAttempt.Value.Add(interval) <= DateTime.Now.ToUniversalTime());

result:

Unsupported where clause: (mo.DateLastAttempt.Value.Add(TimeSpan:(00:01:00)) <= DateTime:(2012-05-31T12:06:09.2683135Z)). 
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
 
Exception Details: System.ArgumentException: Unsupported where clause: (mo.DateLastAttempt.Value.Add(TimeSpan:(00:01:00)) <= DateTime:(2012-05-31T12:06:09.2683135Z)).
 
Stack Trace: 
 
 
[ArgumentException: Unsupported where clause: (mo.DateLastAttempt.Value.Add(TimeSpan:(00:01:00)) <= DateTime:(2012-05-31T12:06:09.2683135Z)).]
   MongoDB.Driver.Linq.SelectQuery.BuildQuery(Expression expression) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Linq\Translators\SelectQuery.cs:862
   MongoDB.Driver.Linq.SelectQuery.BuildQuery(Expression expression) in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Linq\Translators\SelectQuery.cs:827
   MongoDB.Driver.Linq.SelectQuery.Execute() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Linq\Translators\SelectQuery.cs:132
   MongoDB.Driver.Linq.MongoQueryable`1.GetEnumerator() in C:\work\10gen\mongodb\mongo-csharp-driver\Driver\Linq\MongoQueryable.cs:81
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +382
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
   Datavod.Core.Repositories.MessageOutboundRepository.GetNext(TimeSpan interval, Int32 blockSize) in N:\Development\datavod\datavod.core\Repositories\MessageOutboundRepository.cs:84
   Datavod.Core.Services.MessageService.GetNext(TimeSpan interval, Int32 blockSize) in N:\Development\datavod\datavod.core\Services\MessageService.cs:25
   Datavod.Core.BackgroundService.SendMessages.Run() in N:\Development\datavod\datavod.core\BackgroundService\SendMessages.cs:41
   Datavod.Core.BackgroundService.InProcessBackgroundServiceExecutor.Start() in N:\Development\datavod\datavod.core\BackgroundService\InProcessBackgroundServiceExecutor.cs:46
   Datavod.Core.Infrastructure.BootStrapperTasks.LoadBackgroundServices.Execute(IDictionary`2 state) in N:\Development\datavod\datavod.core\Infrastructure\BootStrapperTasks\LoadBackgroundServices.cs:40
   datavod.web.MvcApplication.Application_Start() in N:\Development\datavod\datavod.web\Global.asax.cs:128
 
[HttpException (0x80004005): Unsupported where clause: (mo.DateLastAttempt.Value.Add(TimeSpan:(00:01:00)) <= DateTime:(2012-05-31T12:06:09.2683135Z)).]
   System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +4057141
   System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
   System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +352
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375
 
[HttpException (0x80004005): Unsupported where clause: (mo.DateLastAttempt.Value.Add(TimeSpan:(00:01:00)) <= DateTime:(2012-05-31T12:06:09.2683135Z)).]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11700896
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4869125



 Comments   
Comment by Robert Stam [ 31/May/12 ]

I've reviewed the master branch and we actually DO support queries against Nullable<T>, but the query should be written without using ".Value", so your query should be transformed like this:

// instead of:
query = query.Where(mo => mo.DateLastAttempt.Value.Add(interval) <= DateTime.Now.ToUniversalTime());
 
// use:
query = query.Where(mo => mo.DateLastAttempt <= DateTime.Now.ToUniversalTime().Subtract(interval));

Comment by Robert Stam [ 31/May/12 ]

Not all where clauses are supported. See:

http://www.mongodb.org/display/DOCS/CSharp+Driver+LINQ+Tutorial#CSharpDriverLINQTutorial-Supportedwhereclauses

The general rule is that only where clauses that can be directly mapped to a MongoDB query are supported. One of the requirements of the MongoDB query language is that all comparisons compare a field from the document to a constant (so no computations are allowed as part of the query).

In your particular case, you can slightly rewrite your query to meet this requirement:

// instead of:
query = query.Where(mo => mo.DateLastAttempt.Value.Add(interval) <= DateTime.Now.ToUniversalTime());
 
// use:
query = query.Where(mo => mo.DateLastAttempt.Value <= DateTime.Now.ToUniversalTime().Subtract(interval));

However, that leads to a separate issue: from your use of ".Value" I assume that DateLastAttempt is of type Nullable<DateTime>, and we don't appear to support queries against Nullable<DateTime> yet. So I will leave this JIRA open while I investigate this second issue.

Generated at Wed Feb 07 21:36:58 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.