none
Calling function within extension method. RRS feed

  • Question

  • Hi,

    Lets say I have a query like this;

    var result = from j in dc.get_encokBakilanlar_GroupID(5) select j;
    
    But what I would like to do is;

    var result = from j in dc.Invoke("get_encokBakilanlar_GroupID", params) select j;
    
    I would like to write an extension method which accepts function/method name and parameters, executes it and returns results. How can I achieve this?

     

    Thanks in advance.

    Thursday, July 22, 2010 10:27 AM

Answers

  • Ok, that sounds like get_encokBakilanlar_GroupIDResult is a stored procedure rather than a function. That means it can not be part of a server-side query the same way that a tsql function. (but can still take part in a client side query). Here's an alternative version of Invoke that will allow functions to be composed into queries, and stored procs will be executed immediately for use in L2O queries...

    public IQueryable<T> Invoke<T>(string methodName, params object[] parameters)
    {
      System.Reflection.MethodInfo mi = this.GetType().GetMethod(methodName);
    
      if (mi.ReturnType.GetGenericTypeDefinition().UnderlyingSystemType == typeof(IQueryable<>))
      {
        return this.CreateMethodCallQuery<T>(this, mi, parameters);
      }
      else
      {
        System.Data.Linq.IExecuteResult result = this.ExecuteMethodCall(this, mi, parameters);    
        return ((System.Data.Linq.ISingleResult<T>)(result.ReturnValue)).AsQueryable();
      }
    }
    

       Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools - add-in with new useful features for the L2S and EF designers in VS2008 and VS2010
    huagati.com/L2SProfiler - Query profiler for Linq-to-SQL, Entity Framework v4, and LLBLGen Pro
    • Marked as answer by barbaros Monday, July 26, 2010 8:13 AM
    Saturday, July 24, 2010 9:16 AM
    Answerer

All replies

  • To compile "from j in dc.Invoke("get_encokBakilanlar_GroupID", params) select j;", the compiler would have to know the return type, so Invoke needs to be generic:

    public IQueryable<T> Invoke<T>(string methodName, params object[] parameters)
    {
      System.Reflection.MethodInfo mi = this.GetType().GetMethod(methodName);
      return this.CreateMethodCallQuery<T>(this, mi, parameters);
    }
    
    

    ...alternatively, if you just want to get an IQueryable back without knowing the type at compile time, you could go down the reflection route:

    public IQueryable Invoke(string methodName, params object[] parameters)
    {
      //get hold of the dc method mapped to the db function in methodName
      System.Reflection.MethodInfo mappedMethod = this.GetType().GetMethod(methodName);
      Type mappedEntity = mappedMethod.ReturnType.GetGenericArguments()[0];
    
      //get hold of and create a typed version of CreateMethodCallQuery
      System.Reflection.MethodInfo genericCreateMethod = typeof(System.Data.Linq.DataContext).GetMethod("CreateMethodCallQuery", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
      System.Reflection.MethodInfo typedCreateMethod = genericCreateMethod.MakeGenericMethod(mappedEntity);
    
      //call CreateMethodCallQuery<T>
      return (IQueryable)typedCreateMethod.Invoke(this, new object[] { this, mappedMethod, parameters });
    }
    

    ...both of the two samples above assume that the method and its return type are mapped in the datacontext. If they are not known/mapped by the datacontext, you'll need to emit both at runtime (again, reflection)...


       Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools - add-in with new useful features for the L2S and EF designers in VS2008 and VS2010
    huagati.com/L2SProfiler - Query profiler for Linq-to-SQL, Entity Framework v4, and LLBLGen Pro
    Friday, July 23, 2010 5:17 AM
    Answerer
  • Thanks for your reply. When I try your first approach, I got this error;

    Argument methodInfo does not implement System.Linq.IQueryable`1[MyroDAL.get_encokBakilanlar_GroupIDResult].

    and couldn't solve it. Any clues?

     

    Thanks in advance.

    Friday, July 23, 2010 8:33 AM
  • Thanks for your reply. When I try your first approach, I got this error;

    Argument methodInfo does not implement System.Linq.IQueryable`1[MyroDAL.get_encokBakilanlar_GroupIDResult].

    and couldn't solve it. Any clues?


    Is the method signature matching the expected return type?
       Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools - add-in with new useful features for the L2S and EF designers in VS2008 and VS2010
    huagati.com/L2SProfiler - Query profiler for Linq-to-SQL, Entity Framework v4, and LLBLGen Pro
    Saturday, July 24, 2010 3:38 AM
    Answerer
  • Actually I dont know where to look for. If I look MethodInfo return type, it is System.Data.Linq.ISingleResult `1[MyroDAL.get_encokBakilanlar_GroupIDResult] and exception says "does not implement System.Linq.IQueryable `1[MyroDAL.get_encokBakilanlar_GroupIDResult]".
    Saturday, July 24, 2010 7:59 AM
  • Ok, that sounds like get_encokBakilanlar_GroupIDResult is a stored procedure rather than a function. That means it can not be part of a server-side query the same way that a tsql function. (but can still take part in a client side query). Here's an alternative version of Invoke that will allow functions to be composed into queries, and stored procs will be executed immediately for use in L2O queries...

    public IQueryable<T> Invoke<T>(string methodName, params object[] parameters)
    {
      System.Reflection.MethodInfo mi = this.GetType().GetMethod(methodName);
    
      if (mi.ReturnType.GetGenericTypeDefinition().UnderlyingSystemType == typeof(IQueryable<>))
      {
        return this.CreateMethodCallQuery<T>(this, mi, parameters);
      }
      else
      {
        System.Data.Linq.IExecuteResult result = this.ExecuteMethodCall(this, mi, parameters);    
        return ((System.Data.Linq.ISingleResult<T>)(result.ReturnValue)).AsQueryable();
      }
    }
    

       Kristofer - Huagati Systems Co., Ltd.
    Cool tools for Linq-to-SQL and Entity Framework:
    huagati.com/dbmltools - add-in with new useful features for the L2S and EF designers in VS2008 and VS2010
    huagati.com/L2SProfiler - Query profiler for Linq-to-SQL, Entity Framework v4, and LLBLGen Pro
    • Marked as answer by barbaros Monday, July 26, 2010 8:13 AM
    Saturday, July 24, 2010 9:16 AM
    Answerer
  • if (mi.ReturnType.GetGenericTypeDefinition().UnderlyingSystemType == typeof(IQueryable<>))
    
    This is what I am looking for. Thanks for your help.
    Monday, July 26, 2010 8:14 AM