none
Anyway to get at ToTraceString form LINQ to Entities query?

    Question

  • It looks like a LINQ to Entities query now returns an ObjectResult... is it my imagination or did we get an ObjectQuery from it previously?

     

    SInce LINQ to Entities is tied into object services, is there anyway to get at ToTraceString from it?

     

    Thanks

     

    Julie

    Saturday, December 08, 2007 9:14 PM

Answers

  • In most cases it should be possible to cast IQueryable<T> to ObjectQuery<T>. Try the following extension method that does this automatically:

     

    Code Block

    static string ToTraceString<T>(this IQueryable<T> t)

    {

       // try to cast to ObjectQuery<T>

       ObjectQuery<T> oqt = t as ObjectQuery<T>;

       if (oqt != null)

          return oqt.ToTraceString();

       return "";

    }

     

     

    This even takes care of anonymous types, so you can write:

     

    Code Block

    using (NorthwindEFEntities context = new NorthwindEFEntities())

    {

       // connection must be open in order for ToTraceString() to work

       context.Connection.Open();

       var p = from c in context.Customers

               where c.City == "London"

               select new { Name = c.CompanyName, City = c.City };

       Console.WriteLine(p.ToTraceString());

    }

     

     

    Saturday, December 08, 2007 11:32 PM
    Moderator

All replies

  • In most cases it should be possible to cast IQueryable<T> to ObjectQuery<T>. Try the following extension method that does this automatically:

     

    Code Block

    static string ToTraceString<T>(this IQueryable<T> t)

    {

       // try to cast to ObjectQuery<T>

       ObjectQuery<T> oqt = t as ObjectQuery<T>;

       if (oqt != null)

          return oqt.ToTraceString();

       return "";

    }

     

     

    This even takes care of anonymous types, so you can write:

     

    Code Block

    using (NorthwindEFEntities context = new NorthwindEFEntities())

    {

       // connection must be open in order for ToTraceString() to work

       context.Connection.Open();

       var p = from c in context.Customers

               where c.City == "London"

               select new { Name = c.CompanyName, City = c.City };

       Console.WriteLine(p.ToTraceString());

    }

     

     

    Saturday, December 08, 2007 11:32 PM
    Moderator
  • Just to add a small clarifying comment: A linq query "is" an ObjectQuery<T>, but when you execute it (by enumerating) it returns an ObjectResult<T>.  So as Jarek says, you can cast to ObjectQuery<T> and then call ToTraceString.

     

    - Danny

     

    Sunday, December 09, 2007 12:27 AM
  • That's what I had in mind - forum software ate my <T>

     

    Sunday, December 09, 2007 4:45 AM
    Moderator
  •  

    (Nice use of generics to get around the anonymous type! )

     

    Sorry for the delay - I'm finally getting back to this.

    In my current test, I"m using a stored proc in my query.

     

    Dim qsales = aw.annualCustomerSales("2004")

     

    My extension method is not available on qsales so it's not being seen as an IQueryable. If I explicitly use AsQueryable, then I can call the extension method.

     

    Dim tsql = qsales.AsQueryable.ToTraceString

     

    Then I step into the extension method but when I get to the step where I"m casting the iQueryable to a QueryObject I get an exception that this cast can't be performed:

     

    Unable to cast object of type
    'System.Linq.EnumerableQuery`1[EF3Test.AdventureWorksLTModel.result_annualCustomerSales]'

    to type
    'System.Data.Objects.ObjectQuery`1[EF3Test.AdventureWorksLTModel.result_annualCustomerSales]'

     

    When I try ToTraceString with a query that doesn't use a sproc, it works as expected.

     

    Another thing that's bothering me, though, is that I don't  understand why

     

    Dim qsales = aw.annualCustomerSales("2004")

     

    is an ObjectResult<T>

     

    but in my more standard query (not using a stored procedure),

     

    Dim studclassQuery = From student In school.students From c In student.classes _

    Select student.firstname, student.lastname, c.classname

     

    studclassQuery is an ObjectQuery<T>

     

    Thanks for any insight.

     

    Thursday, December 20, 2007 12:41 AM
  • ObjectResult<T> represents actual results (such as collection of entities) after query has been executed.

    ObjectQuery<T> (which implements IQueryable<T>) represents the query prior to execution (the difference is similar to difference between DbCommand vs DbDataReader).

     

    You can compose queries on top of IQueryable<T> using standard Linq operators and that does not cause them to be executed. When you call Execute() or foreach() the results are calculated and made available as ObjectResult<T>.

     

    Stored procedures are not composable, so they always return ObjectResult<T>.

    Thursday, December 20, 2007 5:35 AM
    Moderator
  • ObjectResult vs. ObjectQuery - okay that's totally logical. The sproc showing up as an ObjectResult is what was throwing me off. Because it was showing as an ObjectResult before it was executed.

     

    And now that I think of it, what's the point of checking the tsql of the stored proc anyway? Duh. It should just be exec mystoredproc. Silly me.

     

    Thanks Jaroslaw.

    Thursday, December 20, 2007 1:21 PM