Pregunta

It's an exercise of EF code-first. There's a simple method. I want to get the Entity SQL command text generated by object services.

(MyDbContext is derived form DbContext. Person is a POCO class.)

using (MyDbContext context = new MyDbContext())
{
    var query = context.Set<Person>().FirstOrDefault(p => p.Age == 1);
    Console.WriteLine(query.Name);


    var objquery = query as ObjectQuery;
    if (objquery != null)
        Console.WriteLine(objquery.CommandText);
}

I used to get native SQL command text by ObjectQuery.TraceString in LINQ to Entity. Now, what I need is Entity-SQL statement, NOT native SQL statement.

But, I can't cast the query from IQueryable<Person> to ObjectQuery or ObjectQuery<Person>. I tried to get members of DbQuery by reflection. It seems that DbQuery hasn't any property about command text or trace string.

Thanks

¿Fue útil?

Solución

My suggestion for what you want is using Dynamic Linq. The library (part of the Linq Samples) includes many IQueryable extensions that return Linq.DataQuery objects. Once you consume the DataQuery you'll have the expected object.

var testQuery =
    db.Cases.
    Where("KeyID > 1").
    Take(1);

foreach (var r in testQuery)
{
    Console.WriteLine(r);
}

Then, you can check against your query as such.

testQuery.Expression
testQuery.Provider

These will give you:

{Table(Case).Where( => (.Keyid > 1)).Take(1)} 
System.Linq.Expressions.Expression {System.Linq.Expressions.MethodCallExpression}

-and-

{SELECT TOP (1) [t0].[Keyid], [t0].[FileNo], [t0].[MatterType], [t0].[LoanNo], [t0].[Investor], [t0].[LoanType], [t0].[Client], [t0].[ClientFileNo], [t0].[ClientStatus], [t0].[Mortgagor], [t0].[County], [t0].[PropertyStreet1], [t0].[PropertyStreet2], [t0].[PropertyCity], [t0].[PropertyState], [t0].[PropertyZipcode], [t0].[Status], [t0].[BoxNo], [t0].[InsurerLoanno], [t0].[InvestorLoanno], [t0].[insurer_name_id], [t0].[OldSystemKey], [t0].[FinalBilling], [t0].[HoldBilling], [t0].[LastModified], [t0].[PiggyLoanNo], [t0].[CurrComentID], [t0].[LockEFILE], [t0].[MSJAmount], [t0].[Created], [t0].[Locked], [t0].[FinalBillingDate], [t0].[HoldBillingDate], [t0].[CreatedBy], [t0].[Stage], [t0].[PriorStage], [t0].[DefendantUpdated], [t0].[VestingCode], [t0].[FileSource], [t0].[SubVestingCode], [t0].[AttorneyAssigment], [t0].[VoluntarySurrender], [t0].[FNMARisk], [t0].[Source], [t0].[REO_ID], [t0].[WTI_ID], [t0].[CaseDismissed], [t0].[REO_CompanyID], [t0].[SubMattertype], [t0].[VendorCode], [t0].[SubType]
FROM [dbo].[Cases] AS [t0]
WHERE [t0].[Keyid] > @p0}
System.Linq.IQueryProvider {System.Data.Linq.DataQuery<CMSDEVMapping.Case>}

You can also verify your type in the loop:

r.GetType() {Name = "Case" FullName = "CMSDEVMapping.Case"} System.Type {System.RuntimeType}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top