0

I have a repository class that has a method to return ObjectSet

something like

public class Repository:ObjectContext
{
  public IObjectSet<T> GetObjectSet()
  {...}
}

When I use this in a query I get linq to entities error ( does not recognize method...)

I like this idea of having a generic repository which doesn't get regenerated every time (with T4 templates) Is there a way to extend the query provider to recognize my method ? But I do want to resolve it on server ( in other words participate in query generation). Sample code that uses it is:

static readonly Func<Repository,
        string, AuthorizedUser>  getInstitutionByAuthorizedUserName = CompiledQuery.Compile(
          (ObjectContext ctx, string userName) =>
              (from inst in ctx.GetObjectSet<Institution>()
              join auths in ctx.GetObjectSet<AuthorizedUser>() 
              on inst.Key equals auths.Institution.Key
              where auths.Name == userName
              select inst.Key).SingleOrDefault();
curtisk
  • 19,950
  • 4
  • 55
  • 71
np-hard
  • 5,725
  • 6
  • 52
  • 76

1 Answers1

0

Don't reinvent CreateObjectSet and break the join habit:

static readonly Func<Repository,
    string, AuthorizedUser>  getInstitutionByAuthorizedUserName = CompiledQuery.Compile(
      (ObjectContext ctx, string userName) =>
          from inst in ctx.CreateObjectSet<Institution>()
          from auths in inst.Authorizations
          where auths.Name == userName
          select inst.Key).SingleOrDefault();
       );
Craig Stuntz
  • 125,891
  • 12
  • 252
  • 273
  • the first example doesnt compile ( lambda expression with a statement body cannot be converted to an expression tree). Also I am creating objectset and caching it since ObjectContext lifetime is over the whole request. – np-hard Jan 24 '11 at 19:30
  • Not in the code you showed, you aren't. Anyway, there's little benefit in "caching" an `ObjectSet`. OC already caches instances, and `ObjectSet` itself is very lightweight. `CompiledQuery`, OTOH, is beleficial, and you're already doing that. Second example is better form anyway, so if the first doesn't work, no loss. :) – Craig Stuntz Jan 24 '11 at 19:39
  • the second example wont compile either (same error as the first one). Agree with you on the join non readability – np-hard Jan 24 '11 at 20:01
  • Well, that code will work outside of an expression (i.e., normal method, not `CompiledQuery`. Inside `CompiledQuery`, you may need to pass the objectSet. Let me update the answer with another version to try. – Craig Stuntz Jan 24 '11 at 20:04
  • 2 problems with this, in compiled query first arg has to be objectcontext, and even if i make that i would get "only scalar parameters are supported error".. – np-hard Jan 24 '11 at 20:19
  • Hmmm... You could try the overload of `CreateObjectSet` which takes a `string`, but barring that you may have to use the strong-typed context for `CompiledQuery`. One more try above, though! See if it works... – Craig Stuntz Jan 24 '11 at 20:36
  • i would get the same error as i was getting with the original question, i think for this to work i really need to able to tell linq to entities provider about my method ( CreateObjectSet<>()) as it only understand a certain set of methods ( surprisingly it understands the property from generated T4) but not a method call with same output type – np-hard Jan 24 '11 at 20:53
  • Generally speaking, L2E can only parse things it can convert to SQL. I think it understands the `ObjectQuery` from the T4 specifically because of its type. IIRC the T4 generates `ObjectQuery`, not `ObjectSet`. – Craig Stuntz Jan 24 '11 at 21:36
  • T4 generates ObjectSet, its just i cant have a generic property because C# doesnt support it. – np-hard Jan 24 '11 at 21:50