tags:

views:

81

answers:

1

Best to describe this in code...

I have this

public class A<T>
{
     public static class Queries
     {
          public static Func<DataContext, int, T>Get =
                CompiledQuery.Compile<DataContext, int, T>(
                    (DataContextdb, int i) => (from t in db.GetTable<T>()
                                                      where t.ID == i
                                                      select t).SingleOrDefault());
     }
}

Can I create a new class and query, like this...

public class B<T>:A<t>
{
      public static class BQueries
      {
          public static Func<DataContext, int, T> Get =
              CompiledQuery.Compile<DataContext, int, T>(
                  (DataContext db, int id) => (from t in A.Queries.Get(db, id)
                                               where !t.Item.Deleted 
                                               select t).SingleOrDefault());
      }

      public abstract TrackingItem Item;
}

All I want to do is compile a new query based on the original that adds a couple constraints. This is in lieu of executing two queries

A: 

It would work if A.Queries.Get(...) returned an IQueryable<>, but as written your code returns a T. However, if you remove SingleOrDefault() it should work fine.

Update: For good measure, this code should work:

public static class Queries
{
    public static Func<DataContext, int, IQueryable<T>>Get =
        CompiledQuery.Compile<DataContext, int, IQueryable<T>>(
            (DataContext db, int i) => from t in db.GetTable<T>()
                                       where t.ID == i
                                       select t);
}

public static class BQueries
{
    public static Func<DataContext, int, IQueryable<T>> Get =
        CompiledQuery.Compile<DataContext, int, IQueryable<T>>(
            (DataContext db, int id) => from t in A.Queries.Get(db, id)
                                        where !t.Item.Deleted 
                                        select t);
}

The queries won't actually execute until you call an immediate operator like SingleOrDefault():

using(var db = new MyDataContext())
{
    var res = BQueries.Get(db, id);
    var entity = res.SingleOrDefault();
    // ...
}
dahlbyk
Well it actually returns T
Antilogic
Ah I see now... that makes sense. I was shooting for deferred execution. Does it even make sense to compile SingleOrDefault into a query?
Antilogic
It's always a tradeoff between usability and the performance cost of parsing the expression. I tend to defer as long as possible, but it depends on your use case.
dahlbyk
Defering execution until last possible moment it my goal here. Is adding SingleOrDefault to the compiled query causing it to execute the minute the query is referenced?
Antilogic
Yes, adding any immediate operator to the end of a compiled query means you'll have a delegate that immediately executes when invoked with the DataContext.
dahlbyk
Gotcha, might explain some of my performance issues
Antilogic