2010-03-17 3 views
6

Pourquoi ne puis-je faire cela:Pourquoi LINQ to Entities ne reconnaît pas certaines méthodes?

usuariosEntities usersDB = new usuariosEntities();  
foreach (DataGridViewRow user in dgvUsuarios.Rows) 
{ 
    var rowtoupdate = 
     usersDB.usuarios.Where(
     u => u.codigo_usuario == Convert.ToInt32(user.Cells[0].Value) 
     ).First(); 
    rowtoupdate.password = user.Cells[3].Value.ToString(); 
} 
usersDB.SaveChanges(); 

et doivent faire:

usuariosEntities usersDB = new usuariosEntities();  
foreach (DataGridViewRow user in dgvUsuarios.Rows) 
{ 
    int usercode = Convert.ToInt32(user.Cells[0].Value); 
    var rowtoupdate = 
     usersDB.usuarios.Where(u => u.codigo_usuario == usercode).First(); 
    rowtoupdate.password = user.Cells[3].Value.ToString(); 
} 
usersDB.SaveChanges(); 

Je dois admettre qu'il est un code plus lisible mais pourquoi ne peux pas faire cela?

Répondre

9

La chose à ce sujet est que les requêtes LINQ sont transformées par le compilateur dans une arborescence d'expression. Cet arbre d'expression est ensuite converti en T-SQL et transmis au serveur. LINQ to SQL mappe certaines méthodes comme String.Contains aux équivalents T-SQL.

Dans le premier exemple, LINQ ne mappe apparemment pas Convert.ToInt32 à quoi que ce soit et l'exception est levée. La raison pour laquelle cela fonctionne dans votre deuxième exemple est parce que l'appel Convert.ToInt32 est fait en dehors de de la requête de sorte qu'il ne fait pas partie de l'arbre d'expression et n'a pas besoin d'être converti en T-SQL.

This MSDN page décrit comment LINQ to SQL traduit différents types de données, opérateurs et méthodes dans T-SQL. (Bien que la documentation suggère Convert.ToInt32 est pris en charge, donc je ne sais pas quoi d'autre peut se passer ici.)

Désolé, il suffit de réaliser ceci est ADO.NET Entity Framework, pas LINQ to SQL. This page lists les mappages ADO.NET Entity Framework. C'est un peu plus restrictif, surtout parce qu'il doit fonctionner avec plusieurs fournisseurs.

+1

Existe-t-il un moyen de faire en sorte que L2E mette en correspondance ces méthodes/fonctions avec les fonctions T-SQL? +1 explication claire – Luiscencio

+0

Non, mais si vous créez une fonction définie par l'utilisateur dans SQL et l'ajoutez à votre contexte de données, vous pouvez les utiliser dans vos requêtes. – Josh

+0

donc si j'utilise mysql et ajoute une procédure stockée à ma base de données, je peux l'appeler en quelque sorte? – Luiscencio

0

Parce que votre LINQ to Ent. ne compile pas la requête dans MSIL avec toutes les méta-données, mais traduit simplement la requête en quelques méthodes d'extantion et est limitée aux capacités d'analyse lambda de la languge. Cela signifie que

ce code:
var results = from c in SomeCollection where c.SomeProperty < someValue * 2 select new {c.SomeProperty, c.OtherProperty};

est la même que celle-ci:

var results = SomeCollection
.Where(c => c.SomeProperty < someValue * 2)
.Select(c => new {c.SomeProperty, c.OtherProperty});

Questions connexes