0

I'm using ASP.NET MVC with C# with Entity Framework 6. I have the following 3 lines of code. x is true.

var x = new List<string>(){"FOO", "BAR"}.Contains("FOO");
var foo = db.TableName.Where(n => new List<string>() { "FOO", "BAR" }.Contains("FOO"));
var bar = foo.ToList();

On the third line an error is thrown: Object reference not set to an instance of an object.

For full clarity, the following lines do not throw any error:

var x = false;
var foo = db.TableName.Where(n => false);
var bar = foo.ToList();

All of the answers I've looked at say that I should check to make sure the list isn't null. I tried that to no avail, then tried defining the list in the LINQ Where call to try to localize the problem. Neither worked.

Why is this throwing an error? What can I do to fix it?

James Gould
  • 2,642
  • 3
  • 24
  • 48
  • What happens when you do `var foo = db.TableName.Where(n => true);` instead of `false`? Do you see an error? – Sergey Kalinichenko Dec 29 '14 at 14:32
  • @dasblinkenlight It returns all the rows of the database, no error. – James Gould Dec 29 '14 at 14:33
  • That's odd. Could you post a stack trace up to the `ToList()` call? – Sergey Kalinichenko Dec 29 '14 at 14:35
  • @TienDinh check my second code sample. You can call tolist even if it returns no rows. – James Gould Dec 29 '14 at 14:36
  • Did you run through the normal "what the hell" checklist? Clean and rebuild, etc? – Jonesopolis Dec 29 '14 at 14:37
  • @Jonesy Yep. Been at this for several hours, because I initially thought the error was somewhere in the new design pattern I was using. – James Gould Dec 29 '14 at 14:38
  • @dasblinkenlight https://gist.github.com/JamesGould123/efb6e8387e38f0420ccd – James Gould Dec 29 '14 at 14:39
  • Try Where(n => (new List() { "FOO", "BAR" }).Contains("FOO") ); – Tien Dinh Dec 29 '14 at 14:39
  • @TienDinh Good idea, but no difference. Note, I was originally working with a predefined list though, just switched to this for troubleshooting. – James Gould Dec 29 '14 at 14:43
  • @JamesG., you should probably make it clear that the third line causes a NRE *way inside the EF code*. On initial reading, I was confused by why this question wasn't a dup too. – Kirk Woll Dec 29 '14 at 14:45
  • Also, why is this your predicate, `n => new List() { "FOO", "BAR" }.Contains("FOO")`? It's equivalent to `n => true`. What are you *really* trying to do? – Kirk Woll Dec 29 '14 at 14:46
  • @KirkWoll it's simply test data. It is apparently not equivalent to `n => true`, as it throws an error, but `n => true` does not. – James Gould Dec 29 '14 at 14:51
  • @JamesG., no kidding. I mean it's *logically* equivalent. I'm trying to help you solve your problem -- I assume you're going to need to massage your query. But I can't give you any suggestions when your example is spurious. – Kirk Woll Dec 29 '14 at 14:52
  • Maybe it need to be list.Contains(columnName), not a literal string – Tien Dinh Dec 29 '14 at 14:52
  • @TienDinh What... that appears to be working. But... I have no idea how I got to this point then. At some point while I was still using the column it started throwing this error. – James Gould Dec 29 '14 at 14:58
  • @KirkWoll I'm trying to check if a column in the table contains one of the strings in the list of strings. – James Gould Dec 29 '14 at 15:02
  • @JamesG., but you don't reference a column in your predicate. That's my point. How do you consume `n`? – Kirk Woll Dec 29 '14 at 15:04
  • Well, this is one of the most annoying mistakes I've made in my career. I was originally calling n.ColName.ToUpper() in the Contains which was throwing my original null reference when n.ColName was null, and while testing I removed n.ColName and replaced it with a test string, which causes a null which creates the same error. Ugh. – James Gould Dec 29 '14 at 15:10
  • I saw the weird expression in the Where clause but i just thought you're trying to stress test EF :) – Tien Dinh Dec 30 '14 at 04:14

1 Answers1

2

Since neither db.TableName.Where(n => false).ToList() nor db.TableName.Where(n => true).ToList() produces an exception, the problem must be in the EF data provider for MySql.

Stack trace that you have posted confirms that assumption: the exception happens at the SQL generation stage, before EF even gets to your data.

[NullReferenceException: Object reference not set to an instance of an object.]
   MySql.Data.Entity.SqlGenerator.Visit(DbPropertyExpression expression) +18
   MySql.Data.Entity.SqlGenerator.Visit(DbInExpression expression) +39
   System.Data.Entity.Core.Common.CommandTrees.DbInExpression.Accept(DbExpressionVisitor`1 visitor) +64
   MySql.Data.Entity.SqlGenerator.VisitBinaryExpression(DbExpression left, DbExpression right, String op) +82
   MySql.Data.Entity.SqlGenerator.Visit(DbAndExpression expression) +49
   ...

In other words, the error has nothing to do with your data. It is caused by data provider's inability to convert a valid conditional expression to SQL. Consider upgrading to the latest .NET connector (unless you are using one already) and/or filing a bug report.

Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399
  • I'll see if upgrading to the latest connector fixes this, do you know where I should file the bug report if it does not? I'm not sure whether this is a bug or expected behavior, apparently the err was that I was using a string, not the column name. – James Gould Dec 29 '14 at 15:12