1

I have this piece of code which check the last customer_id from the db.

ObjectResult<int?> last_customer_id_collection = MainForm.eggsContext.ExecuteStoreQuery<int?>("select MAX(customer_id) from customers");

Then I get the next id required like this

new_customer_id = last_customer_id_collection.FirstOrDefault<int?>().Value + 1;

It's working, HOWEVER when dealing with a new empty db the statment last_customer_id_collection.FirstOrDefault<int?>() throws an InvalidOperationException.

How can I check if last_customer_id_collection was empty without try catch?

(p.s. I was trying to check if last_customer_id_collection.Any<int?>() or last_customer_id_collection.Count<int?>() or DefaultIfEmpty etc. but everything I try causes this exception)

BornToCode
  • 9,495
  • 9
  • 66
  • 83
  • 4
    What's the exception message? – SLaks Jun 24 '12 at 13:19
  • Why are you including ``? Is the collection actually of type `int?` or `int` or something else? I suspect this could be the root of your problem. – Tim S. Jun 24 '12 at 13:21
  • Could you post the Stacktrace and/or the exception message? So we could see whats going on here exactly. It may be that your database connection is causing the ``InvalidOperationException`` because the actual call to the database gets deferred until you call ``FirstOrDefault``. – Philip Daubmeier Jun 24 '12 at 13:35

1 Answers1

1

You get an InvalidOperationException because Nullable<T>.HasValue would return false.

You will need to modify the code to not call .Value if the query return value is null.

var custId = last_customer_id_collection.FirstOrDefault<int?>();
if(custId.HasValue)
    DoStuffWithId();
else
    DoStuffWithNullResult();

Small Example that demonstrates the potentialy confusing behaviors of Nullables This will print:

"Null!", "No Value but no NullReferenceException" and then "Oops, InvalidOperationException"

List<int?> values = new List<int?>();

var test = values.FirstOrDefault();

if (test == null)
    Console.WriteLine("Null!");

if (test.HasValue)
    Console.WriteLine(test.Value);
else
    Console.WriteLine("No Value but no NullReferenceException");

try
{
    int value = test.Value;
}
catch(InvalidOperationException)
{
    Console.WriteLine("Oops, InvalidOperationException");
}
Jf Beaulac
  • 5,206
  • 1
  • 25
  • 46
  • What exactly is the difference between your answer an Michaels? This is does not seem to be the problem here, as it would throw a NullReferenceException, not an InvalidOperationException. Edit: Michael just deleted his answer... – Philip Daubmeier Jun 24 '12 at 13:31
  • No it would not throw a NullReferenceException because he's using int? – Jf Beaulac Jun 24 '12 at 13:39
  • Your right, just checked it: ``(new int?[] { null, 2, 3 }).FirstOrDefault().Value;`` throws an ``InvalidOperationException`` indeed. Didnt know that. +1 for you :) – Philip Daubmeier Jun 24 '12 at 13:42
  • 1
    added a small example that demonstrates how you can get the InvalidOperationException but no NullReferenceException, and how you can call HasValue on a variable that test true to a null check. – Jf Beaulac Jun 24 '12 at 13:51
  • You're a genius. But I still can't understand why when debugging and trying to evaluate last_customer_id_collection.FirstOrDefault() from the watch window it gives the InvalidOpertationException, but from the code `var custId = last_customer_id_collection.FirstOrDefault()` it doesn't throw that exception?? – BornToCode Jun 24 '12 at 14:00