[CSHARP-502] NullReferenceException on First() call Created: 19/Jun/12  Updated: 20/Mar/14  Resolved: 28/Jun/12

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

Type: Bug Priority: Critical - P2
Reporter: Rick B. Assignee: Unassigned
Resolution: Done Votes: 0
Labels: crash, linq, query
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

VS 2010, MongoDB 2.0.2, Windows 7x64



 Description   

I am having issues with the latest MongoDB C# driver (v1.4.2.4500) crashing when I query this document:

{
"_id" : "4fdfe705b48c6b24dcab994a",
"CreatedDate" : new Date("6/18/2012 19:42:13"),
"UpdatedDate" : new Date("6/18/2012 19:42:13"),
"SiteId" : "4fdfe705b48c6b24dcab9939",
"ClientId" : "4fdfe705b48c6b24dcab9937",
"Account" :

{ "UserName" : "blah", "Password" : null, "PasswordSalt" : null, }

,
"FbAccount" :

{ "_id" : "838331911", "access_token" : ".....", "Pages" : [] }

}

Query:

var q1 = from u in this.Repository.All<User>()
where u.FbAccount.Id == "832631911"
select u;

var foo1 = q1.First();

Repository:

public IQueryable<T> All<T>() where T : class, new()
{
return this.GetQuery<T>().FindAll().AsQueryable();
}

Exception:

[NullReferenceException: Object reference not set to an instance of an object.]
lambda_method(Closure , User ) +137
System.Linq.WhereEnumerableIterator`1.MoveNext() +155
System.Linq.Enumerable.First(IEnumerable`1 source) +244
lambda_method(Closure ) +322
System.Linq.Queryable.First(IQueryable`1 source) +382
AuctionCMS.Framework.Services.ClientService.GetByFacebookUserId(String fbUserId) in ClientService.cs:39

Am I doing something wrong or is this a bug?



 Comments   
Comment by Rick B. [ 20/Jun/12 ]

Got it. Thank you again for the assistance.

Comment by Robert Stam [ 20/Jun/12 ]

LINQ to MongoDB does not support joins (neither does the underlying MongoDB native query language for that matter).

You'll have to read the collections one at a time.

Comment by Rick B. [ 20/Jun/12 ]

Yes, just the exception is being thrown.

I change the repository code to remove the FindAll() call. However, now I am getting a "SelectMany" is not supported error when I call ToList().

How should I handle queries like this?

var q = from e in this.Repository.All<EmailAddress>()
from u in this.Repository.All<User>()
from c in this.Repository.All<Client>()
where e.Address.ToLowerInvariant() == email.ToLowerInvariant() && u.Id == e.UserId && u.Id == c.PrimaryStaffMemberId && c.Id == u.ClientId
select u;

IList<IUser> entities = q.Cast<IUser>().ToList();

Thanks for the help!

Comment by Craig Wilson [ 20/Jun/12 ]

When you say "crash", what do you mean? Was there something else that happened other than the NullReferenceException?

Comment by Robert Stam [ 20/Jun/12 ]

I'll look into it, but if you look at your stack trace the exception didn't come from the C# driver, it came from LINQ. I don't know if it's possible to avoid this exception (other than not calling AsQueryable on the result of FindAll...).

Comment by Rick B. [ 20/Jun/12 ]

I'll make the change tomorrow. Thank you.

Either way though, the driver shouldn't have crashed right?

Comment by Robert Stam [ 20/Jun/12 ]

So GetQuery<T> actually returns a MongoCollection<T>? The name is a bit misleading...

To repeat my earlier comment, you should call AsQueryable<T> on a MongoCollection<T>, not on the result of calling FindAll. Once you call FindAll you've left the LINQ world and are dealing with an IEnumerable<T> result set.

See the code sample in my previous comment, and let me know if that didn't answer your question.

Comment by Rick B. [ 20/Jun/12 ]

This is the GetQuery() method and supporting Database property:

private MongoDatabase DataBase
{
get
{
if (db == null)

{ db = provider.GetDatabase(this.databaseName); }

return db;
}
}

public MongoCollection<T> GetQuery<T>() where T : class, new()

{ var query = DataBase.GetCollection<T>(typeof(T).Name + "s"); return query; }

Does this look right? I can send you my whole repository file if you like.

Thanks!

Comment by Robert Stam [ 19/Jun/12 ]

You shouldn't be calling AsQueryable on the result of FindAll. Calling FindAll will result in all documents being returned from the server, so caling AsQueryable doesn't make sense.

Also not sure what your GetQuery<T> method does.

The way to do a LINQ query is to call AsQueryable<T> on the MongoCollection object.

var query = from u in userCollection.AsQueryable<User>()
where u.FbAccount.Id == "832631911"
select u;

You can use helper methods if you want as long as they end up doing the same thing as the sample code.

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