[CSHARP-507] System.NullReferenceException on Empty String comparison Created: 20/Jun/12  Updated: 20/Mar/14  Resolved: 04/Jul/12

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

Type: Bug Priority: Major - P3
Reporter: Zaid Masud Assignee: Robert Stam
Resolution: Done Votes: 0
Labels: linq, linq,query
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The following code gives us a NullReferenceException in FirstOrDefault() implementation:

collection.AsQueryable().Where(d => d.StringField == String.Empty).Select(d => d.SomeField).FirstOrDefault()



 Comments   
Comment by Zaid Masud [ 04/Jul/12 ]

Thanks... I would consider an additional unit test for SingleOrDefault() as well although your fix seems to apply for both.

Comment by Robert Stam [ 04/Jul/12 ]

Zaid, thanks for the additional information. That really helped in reproducing this and in coming up with a fix.

The exception is only thrown if FirstOrDefault is called after a projection that returns a struct (bool is a struct), which is why we hadn't seen this before.

Comment by auto [ 04/Jul/12 ]

Author:

{u'date': u'2012-07-03T14:44:59-07:00', u'name': u'Robert Stam', u'email': u'robert@10gen.com'}

Message: CSHARP-507: Support FirstOrDefault when LINQ query includes a projection to a struct and doesn't match any documents (which was failing because null can't be cast to a struct).
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/3d8d92a60ed62055201c1b11de7b715e71474392

Comment by Zaid Masud [ 03/Jul/12 ]

System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=MongoDB.Driver
StackTrace:
at MongoDB.Driver.Linq.MongoQueryProvider.Execute[TResult](Expression expression) in C:\Users\ZAID\Documents\GitHub\mongo-csharp-driver\Driver\Linq\MongoQueryProvider.cs:line 130
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at MongoDriverBug.Program.Main() in C:\MongoDriverBug\MongoDriverBug\Program.cs:line 24
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

Comment by Zaid Masud [ 03/Jul/12 ]

using System;
using System.Linq;
using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Driver.Linq;

namespace MongoDriverBug
{
class Program
{
public class Document
{
public ObjectId Id

{ get; set; }
public bool BoolField { get; set; }

}

static void Main()

{ MongoDatabase db = MongoServer.Create("mongodb://localhost/?safe=true").GetDatabase("test"); db.DropCollection("Document"); IQueryable<Document> documents = db.GetCollection<Document>("Document").AsQueryable(); Console.WriteLine(documents .Where(d => d.Id == ObjectId.GenerateNewId()) .Select(d => d.BoolField) .FirstOrDefault()); Console.ReadKey(); }

}
}

Comment by Zaid Masud [ 03/Jul/12 ]

This turned out to be a slightly different issue.

The empty string was causing no matches.

So to re-phrase, the exception is thrown when there is a Where().Select().FirstOrDefault when the where clause results in no matches returned.

i.e.

collection.AsQueryable().Where(d => d.Id == ObjectId.GenerateNewId()).Select(d => d.BoolField).FirstOrDefault();

In our specific case, the field being selected is a boolean type but I'm not sure whether that is relevant.

Comment by Craig Wilson [ 28/Jun/12 ]

I cannot reproduce this. If you could provide a stack trace of the error and a sample program to reproduce it, that would be immensely helpful. My program is below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Bson;
using MongoDB.Driver.Linq;
using System.Collections.ObjectModel;
using MongoDB.Bson.Serialization;

namespace GeneralConsole
{
class Program
{
public class Person
{
public ObjectId Id

{ get; set; }
public string Firstname { get; set; }

public string Lastname

{ get; set; }

}

static void Main(string[] args)
{
// Construct Objects
Person person = new Person

{ Firstname = string.Empty, Lastname = "funny" }

;

// Connect to Mongo
var server = MongoServer.Create("mongodb://localhost/?safe=true");
var db = server.GetDatabase("test");
db.DropCollection("parents");
var collection = db.GetCollection<Person>("parents");
collection.Save(new Person

{ Firstname = string.Empty, Lastname = null }

);
collection.Save(new Person

{ Firstname = null, Lastname = string.Empty }

);

var parentName = collection.AsQueryable()
.Where(x => x.Firstname == string.Empty)
.Select(x => x.Firstname)
.FirstOrDefault();

parentName = collection.AsQueryable()
.Where(x => x.Lastname == string.Empty)
.Select(x => x.Lastname)
.FirstOrDefault();

Console.ReadKey();
}
}
}

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