Почему LINQ to Entities не распознает определенные методы? - PullRequest
6 голосов
/ 18 марта 2010

Почему я не могу сделать это:

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();

И нужно сделать это:

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();

Я должен признать, что это более читаемый код, но почему это нельзя сделать?

Ответы [ 2 ]

9 голосов
/ 18 марта 2010

Дело в том, что запросы LINQ преобразуются компилятором в дерево выражений. Это дерево выражений затем преобразуется в T-SQL и передается на сервер. LINQ to SQL отображает определенные методы, такие как String.Contains, в эквиваленты T-SQL.

В первом примере LINQ, очевидно, не отображает Convert.ToInt32 ни на что, и генерируется исключение. Причина, по которой он работает во втором примере, заключается в том, что вызов Convert.ToInt32 выполняется вне запроса, поэтому он не является частью дерева выражений и не нуждается в преобразовании в T-SQL.

Эта страница MSDN описывает, как LINQ to SQL переводит различные типы данных, операторы и методы в T-SQL. (Хотя документация предполагает, что Convert.ToInt32 поддерживается, поэтому я не уверен, что еще здесь может происходить.)

Извините, только что понял, что это ADO.NET Entity Framework, а не LINQ to SQL. На этой странице перечислены сопоставления ADO.NET Entity Framework. Это немного более ограничительно, в основном потому, что ему нужно работать с несколькими провайдерами.

0 голосов
/ 18 марта 2010

Потому что ваш LINQ to Ent. не компилирует запрос в MSIL со всеми метаданными, а просто переводит запрос в несколько методов вычитания и ограничивается возможностями разбора лямбда-языка. Это означает, что

этот код:
var results = from c in SomeCollection where c.SomeProperty < someValue * 2 select new {c.SomeProperty, c.OtherProperty};

так же, как это:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...