2009-02-15 6 views
12

Je souhaite traduire l'arborescence d'expression LINQ en instruction SQL et je ne souhaite pas écrire mon propre code pour cela.Traduire l'instruction LINQ en SQL

Exemple:

var query = from c in Customers 
where c.Country == "UK" && 
     c.City == "London" 
select c); 

Pour

SELECT ... FROM Customers AS c WHERE c.Country = "UK" AND c.City = "London" 

Je sais DataContext.Log, mais je veux utiliser:

query.ToSqlStatementString() 

Répondre

17
CustomDataContext dc = new CustomDataContext(); 
IQueryable<Customer> query = 
    from c in dc.Customer 
    where c.Country == "UK" 
    select c; 
// 
string command = dc.GetCommand(query).CommandText; 
+0

C'est bon:) ... mais j'ai besoin d'une connexion db ouverte pour que cela fonctionne :) (Je ne sais pas pourquoi:)) ... savez-vous comment d'une autre façon? – zielu1

10

La réponse de David B vous obtient ce que vous voulez, mais il y a le coût caché de requirin g une connexion à une base de données. La raison pour laquelle cela est fait est de déterminer la version du serveur SQL en demandant au serveur lui-même. Pour éviter cela, vous devez utiliser cet extrait de code:

/// <summary> 
/// Through reflection (HACK) this sets the MS impl of LINQ-to-SQL to not attempt connection to the database just 
/// to determine the SQL server version running to tailor the SQL query to. 
/// </summary> 
private static void hack_SetLINQ2SQLProviderMode(CustomDataContext db) 
{ 
    object provider = hack_GetLINQ2SQLProvider(db); 

    provider 
     .GetType() 
     .GetField("mode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) 
     .SetValue(provider, 2); 
} 

private static object hack_GetLINQ2SQLProvider(CustomDataContext db) 
{ 
    return db 
     .GetType() 
     .GetProperty("Provider", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) 
     .GetValue(_db, new object[0]); 
} 

Appel hack_SetLINQ2SQLProviderMode(db)db est votre DataContext classe dérivée.

Cela définira le champ mode de l'implémentation MS de IQueryProvider de LINQ vers SQL pour indiquer que vous voulez générer du code SQL pour MS SQL Server 2005, indiqué par SetValue(provider, 2). Utilisez 1 pour MS SQL Server 2000 ou 3 pour MS SQL Server 2008.

Cela signifie que, puisque le champ mode est défini, la mise en œuvre n'a plus besoin d'ouvrir la connexion SQL à la base de données et vous pouvez maintenant travailler complètement déconnecté.

S'il vous plaît noter que cela utilise une réflexion en pleine confiance, d'après ce que je comprends. Vous ne devez utiliser cette approche que dans un environnement que vous contrôlez et qui approuve entièrement votre assembly.

+1

* Boggle *. Soigné. –