views:

3330

answers:

5

I just asked this question. Which lead me to a new question :)

Up until this point, I have used the following pattern of selecting stuff with Linq to SQL, with the purpose of being able to handle 0 "rows" returned by the query:

var person = (from p in [DataContextObject].Persons
              where p.PersonsID == 1
              select new p).FirstOrDefault();

if (person == null)
{
    // handle 0 "rows" returned.
}

But I can't use FirstOrDefault() when I do:

var person = from p in [DataContextObject].Persons
             where p.PersonsID == 1
             select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode };

// Under the hood, this pattern generates a query which selects specific
// columns which will be faster than selecting all columns as the above
// snippet of code does. This results in a performance-boost on large tables.

How do I check for 0 "rows" returned by the query, using the second pattern?



UPDATE:

I think my build fails because I am trying to assign the result of the query to a variable (this._user) declared with the type of [DataContext].User.

this._user = (from u in [DataContextObject].Users
              where u.UsersID == [Int32]
              select new { u.UsersID }).FirstOrDefault();

Compilation error: Cannot implicitly convert type "AnonymousType#1" to "[DataContext].User".

Any thoughts on how I can get around this? Would I have to make my own object?

+1  A: 
if (person.Any()) /* ... */;

OR

if (person.Count() == 0) /* ... */;
Mark Cidade
A: 

You can still use FirstOrDefault. Just have "var PersonFields = (...).FirstOrDefault()". PersonFields will be be null or an object with those properties you created.

Peter
+7  A: 

Why can you keep doing the samething? Is it giving you an error?

var person = (from p in [DataContextObject].Persons
              where p.PersonsID == 1
              select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode }).FirstOrDefault();

if (person == null) {    
    // handle 0 "rows" returned.
}

It is still a reference object just like you actual object, it is just anonymous so you don't know the actual type before the code is compiled.

Nick Berardi
Agreed, the above should work, unless there's an unrelated runtime error.
Codewerks
Updated my question.
roosteronacid
+1  A: 

Regarding your UPDATE: you have to either create your own type, change this._user to be int, or select the whole object, not only specific columns.

liggett78
+1  A: 

Update:

I see now what you were actually asking! Sorry, my answer no longer applies. I thought you were not getting a null value when it was empty. The accepted response is correct, if you want to use the object out of scope, you need to create a new type and just use New MyType(...). I know DevEx's RefactorPro has a refactoring for this, and I think resharper does as well.

Call .FirstOrDefault(null) like this:

string[] names = { "jim", "jane", "joe", "john", "jeremy", "jebus" };
var person = (
    from p in names where p.StartsWith("notpresent") select 
        new { Name=p, FirstLetter=p.Substring(0,1) } 
    )
    .DefaultIfEmpty(null)
    .FirstOrDefault();

MessageBox.Show(person==null?"person was null":person.Name + "/" + person.FirstLetter);

That does the trick for me.

Andrew Backer