tags:

views:

66

answers:

4

Hi there,

Hoping this is a nice softball of a question for a friday but I have the following line of code:

//System.ArgumentOutOfRangeException generated if there is no matching data
currentAnswers = new CurrentAnswersCollection()
    .Where("PARTICIPANT_ID", 10000).Load()[0];

CurrentAnswersCollection is a strongly-typed collection populated by a view going back to my database. The problem of course is that if there is not a corresponding PARTICIPANT_ID = 10000 I get the error message.

Is there a better way to write this so that I wouldn't get the error message at all? I just dont know enough about LINQ syntax to know if I can test for the existance first?

thanks.

+7  A: 

Use this:

currentAnswers = new CurrentAnswersCollection()
    .Where("PARTICIPANT_ID", 10000).Load()
    .FirstOrDefault();

It'll return null if there is no first element.

But you may need to fix your code (replicated here) first - the .Where syntax looks dodgy.

David M
Did you actually try to run this code? It shouldn't even compile. .Where needs a lambda. Here's the reference: http://msdn.microsoft.com/en-us/library/bb534803.aspx
Cylon Cat
Very true - up to the .FirstOrDefault, this was just the OP's code returned to him.
David M
@Cylon Cat, he could be using Dynamic LINQ library. http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Matthew Whited
It's not necessarily true that FirstOrDefault will return null for an empty Enumeration. If the Enumeration contains say int it will return 0. As it name suggests it returns the default if empty which is null for reference types.
juharr
True, I assumed from the naming that this was a reference type.
David M
Many thanks, that worked fine for me!
SomeMiscGuy
A: 
You need a lambda expression in .Where.

currentAnswers = new CurrentAnswersCollection().Where(c => c.PARTICIPANT_ID == 10000).Load().FirstOrDefault(); 
Cylon Cat
His code seems to work, except when there are no items returned. "Lambda" is not the problem, "[0]" is.
ANeves
The question had two parts, the lack of == and the exception. Cylon Cat answered the == part.
Panagiotis Kanavos
@ANeves, "seems to work"? Every overload of IEnumerable .Where() requires a delegate. There's no way that .Where can work when the first parameter is a string.
Cylon Cat
Guys, he could be very well using Dynamic LINQ. It doesn't have to use lambda expressions http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Matthew Whited
@Cylon Cat, had this been part of this problem he would have a compiler error and not a runtime exception.
Matthew Whited
@Cylon Cat, I thought *exactly* what you thought. But then reading his question and explanation of the problem it seems like it was working, just not when returning 0 items... So I shrugged and disregarded the apparent syntax problem.
ANeves
A: 

Try:

var answers = new CurrenAnswersCollection().Where("PARTICIPANT_ID", 10000);
if(answers.Count() >= 1) currentAnswers = answers.Load()[0];

or something similar.

AllenG
+1  A: 

The ArgumentOutOfRangeException is occurring when you try to use the indexer to get the first item from the (empty) list. Using the FirstOrDefault() extension method is a convenient way to return the first element of a collection, if there is one, otherwise to return null.

currentAnswers = new CurrentAnswersCollection().Where("PARTICIPANT_ID", 10000)
                                               .Load()
                                               .FirstOrDefault();

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.firstordefault.aspx

MicScoTho