views:

160

answers:

4

(I've put "...to Entities" in brackets since I don't know if this matters at all. I guess this is a quite general LINQ related question.)

I want to check with LINQ (to Entities) if an object exists in the database. At the moment I am doing the following:

using (MyEntitiesContext aCtx = new MyEntitiesContext())
{
    var aQuery = from c
                 in aCtx.Client
                 where c.ClientID==1
                 select c;

    Client aClient = aQuery.FirstOrDefault();

    bool Exists = (aClient!=null);
    ...
}

But (if I am not wrong) this loads the full Client object from the database (if the Client exists). I am actually only interested whether it exists or not without loading the object.

SQL has the SELECT COUNT(*)... construct. Is there something similar I can do with LINQ?

Thank you for advice!

A: 

You could try...

using (MyEntitiesContext aCtx = new MyEntitiesContext())
{
     var aQuery = from c
         in aCtx.Client
         where c.ClientID==1
         select c;

     int total = aQuery.Count();

     bool Exists = (total > 0);
     ...
}

Untested...

TGnat
[Never use `Count()` when you mean `Any()`](http://blogs.teamb.com/craigstuntz/2010/04/21/38598/)
Craig Stuntz
+4  A: 

One option is to use the Any method of IQueryable. It will return a boolean value indicating whether or not an object was found matching the specified condition.

using (MyEntitiesContext aCtx = new MyEntitiesContext())
{
    bool exists = (from c
                   in aCtx.Client
                   where c.ClientID==1
                   select c).Any();
}

This method will also stop running as soon as it evaluates to true.

PatrickJ
That's a nice compact expression, thank you!
Slauma
A: 

You can use the Count() operator or the Any Operator on your query to check if it would return a result:

using (MyEntitiesContext aCtx = new MyEntitiesContext())
{
    var aQuery = from c
                 in aCtx.Client
                 where c.ClientID==1
                 select c;

    int count = aQuery.Count();

    bool Exists = (count > 0);

    // or
    Exists = aQuery.Any();

    ...
}
Johannes Rudolph
+2  A: 

I would then use Any() to determine existence. Regardless of whether you create a dummy instance like the following, the compiler will create a SQL statement using the Exists function and thus, it will not matter what is in the Select statement.

var query= from c
            in context.Client
            where c.ClientID == 1
            select new { Dummy = "foo" };

var exists = query.Any();
Thomas
Hm, does this mean that without this dummy object the `Any()` method would still cause the Client object to be loaded from the database?
Slauma
There is no "dummy instance" here, despite what the answer says. The code shown will never materialize/instantiate any instance. Try it and see; the code works correctly even if the text above it is a little misleading.
Craig Stuntz
OK, I understand. But then does it make any difference to write `select new { Dummy = "foo" }` instead of `select c` as the other answers suggested?
Slauma
@Slauma - Remember that LINQ does not actually execute until you use the query so the query gets executed on the call to `Any`. Thus, it is technically correct to say that the Dummy instance never gets created. By "create", I should have said "declare" which I'll change here shortly. If you use Select c, I believe the system will query for c using Select *. That I'll have to test.
Thomas
@Slauma - Looking at the resulting SQL, it shouldn't matter whether you use `select c` or create a dummy instance. When you use `Any`, the compiler is smart enough to use an `Exists` function.
Thomas
@Thomas: Great, thank you for this analysis!
Slauma