2009-07-01 3 views
185
var items = from c in contacts 
      select new ListItem 
      { 
       Value = c.ContactId, //Cannot implicitly convert type 'int' (ContactId) to 'string' (Value). 
       Text = c.Name 
      }; 
var items = from c in contacts 
      select new ListItem 
      { 
       Value = c.ContactId.ToString(), //Throws exception: ToString is not supported in linq to entities. 
       Text = c.Name 
      }; 

Есть ли в любом случае я могу достичь этого? Обратите внимание, что в VB.NET нет проблем с использованием первого фрагмента, который он отлично работает, VB является гибким, im неспособным привыкнуть к строгости C# !!!Проблема с преобразованием int в строку в Linq для объектов

+1

.ToString() не работает для LinqToEF в VB. ИМХО, вроде глупо. – StingyJack

+4

@StingyJack, проблема связана с ELINQ (объектами linq 2), потому что он переводит ваш код в SQL, а когда дело доходит до внутреннего запроса ToString, он не знает, как перевести «ToString» на SQL. В отличие от linq 2 объектов, когда нет перевода, и все это CLR lambdas, то оно выполняется непосредственно на запрошенных объектах. – Shimmy

+0

Я просто раздражен тем, что они позволяют компилировать такую ​​ошибку, и что мне приходилось постоянно трогать, чтобы найти простое английское описание причины (без юридического и академического). – StingyJack

ответ

290

С EF v4 вы можете использовать SqlFunctions.StringConvert. Нет перегрузки для int, поэтому вам нужно использовать двойную или десятичную. Ваш код будет выглядеть так:

var items = from c in contacts 
      select new ListItem 
      { 
       Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(), 
       Text = c.Name 
      }; 
+223

Почему бы им не включить перегрузку для int? –

+0

Это не работает для меня, ошибка изменяется на: Указанный метод «System.String StringConvert (System.Nullable'1 [System.Double])» на тип «System.Data.Objects.SqlClient.SqlFunctions» не может быть преобразованный в выражение LINQ to Entities store. – Nestor

+1

Как выглядит часть 'SqlFunctions.StringConvert' вашего запроса? Из ошибки кажется, что вы передаете 'Nullable ' ('double?') Вместо 'double'. Попробуйте вызвать 'GetValueOrDefault()' перед тем, как передать его. –

-5

Вы можете попробовать:

var items = from c in contacts 
     select new ListItem 
     { 
      Value = Convert.ToString(c.ContactId), 
      Text = c.Name 
     }; 
+2

Нет. не работает – Shimmy

+0

Вышеприведенный код не будет работать, поскольку он вызовет ошибку: «LINQ to Entities не распознает метод« System.String ToString (Int32) », и этот метод не может быть переведен в выражение хранилища». –

-2

Я понимаю, что вы должны создать частичный класс «продлить» свою модель и добавить свойство, которое только для чтения, которые могут использовать остальные свойства класса.

public partial class Contact{ 

    public string ContactIdString 
    { 
     get{ 
      return this.ContactId.ToString(); 
     } 
    } 
} 

Тогда

var items = from c in contacts 
select new ListItem 
{ 
    Value = c.ContactIdString, 
    Text = c.Name 
}; 
+0

Нет, вы не можете использовать пользовательские свойства в LINQ to Entities (в .NET 3.5). –

+1

Я не тестировал его, но он тоже не будет работать. , поскольку это не свойство поля таблицы. Я мог бы сначала сделать это с помощью ToArray(), а затем linqing над объектами, но я хочу запросить DB. Я предполагаю, что это не удастся. Я создал свой собственный ListItem, который принимает поле int. Это работает лучше для меня. – Shimmy

6
public static IEnumerable<SelectListItem> GetCustomerList() 
     { 
      using (SiteDataContext db = new SiteDataContext()) 
      { 
       var list = from l in db.Customers.AsEnumerable() 
          orderby l.CompanyName 
          select new SelectListItem { Value = l.CustomerID.ToString(), Text = l.CompanyName }; 

       return list.ToList(); 
      } 
     } 
+0

Вы протестировали его, и он работает? прочитайте [this] (http://stackoverflow.com/questions/1066760/problem-with-converting-int-to-string-in-linq-to-entities/1066781#1066781) ответ раньше. – Shimmy

+0

Да, я уже использую его. Он работает для MVC3, EF4, CTP5, SQL CE4. – Nestor

+0

Это кажется более элегантным, чем бокс, чтобы удвоить и использовать StringConvert. – CmdrTallen

2

Я столкнулся с этой же проблемой, когда я преобразовать мое приложение MVC 2 в MVC 3 и просто дать другое (чистое) решение этой проблемы я хочу сообщение, что я сделал ...

IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(), 
    "ID", "Name", model.ProducerID); 

GetProducers() просто возвращает коллекцию сущностей производителей. P.S. SqlFunctions.StringConvert не работал для меня.

4

SqlFunctions.StringConvert будет работать, но я нахожу это громоздким, и большую часть времени у меня нет реальной необходимости выполнять преобразование строк на стороне SQL.

Что я делаю, если я хочу выполнять строковые манипуляции, сначала выполняет запрос в linq-to-entity, а затем манипулирует укусами в linq-to-objects. В этом примере я хочу получить набор данных, содержащих полное имя контакта, и ContactLocationKey, который является конкатенацией строк из двух столбцов Integer (ContactID и LocationID).

// perform the linq-to-entities query, query execution is triggered by ToArray() 
var data = 
    (from c in Context.Contacts 
    select new { 
     c.ContactID, 
     c.FullName, 
     c.LocationID 
    }).ToArray(); 

// at this point, the database has been called and we are working in 
// linq-to-objects where ToString() is supported 
// Key2 is an extra example that wouldn't work in linq-to-entities 
var data2 = 
    (from c in data 
    select new { 
     c.FullName, 
     ContactLocationKey = c.ContactID.ToString() + "." + c.LocationID.ToString(), 
     Key2 = string.Join(".", c.ContactID.ToString(), c.LocationID.ToString()) 
    }).ToArray(); 

Теперь, я допускаю, что это действительно становится громоздким, чтобы написать два анонимных выбирает, но я бы сказал, что перевешивает удобство которого вы можете выполнить строку (и другие) функции не поддерживаются в L2E. Также имейте в виду, что с помощью этого метода возможно ограничение производительности.

4
var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({ 
    Text = a.ClassName, 
    Value = a.ClassId.ToString() 
}); 

Во-первых, конвертировать в объект, то toString() будет правильным.

12

Я решил аналогичную проблему, поставив преобразование целого числа в строку из запроса. Это может быть достигнуто путем помещения запроса в объект.

var items = from c in contacts 
      select new 
      { 
       Value = c.ContactId, 
       Text = c.Name 
      }; 
var itemList = new SelectList(); 
foreach (var item in items) 
{ 
    itemList.Add(new SelectListItem{ Value = item.ContactId, Text = item.Name }); 
} 
2

Если ваш «контакт» действует как общий список, я надеюсь, что следующий код работает хорошо.

var items = contact.Distinct().OrderBy(c => c.Name) 
           .Select(c => new ListItem 
           { 
           Value = c.ContactId.ToString(), 
           Text = c.Name 
           }); 

Спасибо.

-2
var items = from c in contacts 
select new ListItem 
{ 
    Value = String.Concat(c.ContactId), //This Works in Linq to Entity! 
    Text = c.Name 
}; 

Я обнаружил, что SqlFunctions.StringConvert((double)c.Age) не работает для меня либо поле типа Nullable<Int32>

Принял меня много поисков в течение последних нескольких дней проб и ошибок, чтобы найти это.

Надеюсь, это поможет нескольким кодировщикам.

+1

Не работает для меня. Он выдает исключение «* ...' System.String Concat (System.Object) 'не может быть переведено в выражение хранилища ... *". – Slauma

+1

Не работает и для меня. Я также получаю «System.NotSupportedException: LINQ to Entities не распознает метод« System.String Concat (System.Object) », и этот метод не может быть переведен в выражение хранилища». – camainc

+1

НЕ РАБОТАЕТ - ДЕВОТИРОВАТЬ ЭТО ОТВЕТ [NotSupportedException: LINQ to Entities не распознает метод «System.String Concat (System.Object)», и этот метод не может быть переведен в выражение хранилища.] –

8

Использование LinqToObject: контакты. AsEnumerable()

var items = from c in contacts.AsEnumerable() 
      select new ListItem 
      { 
       Value = c.ContactId.ToString(), 
       Text = c.Name 
      }; 
+0

Спасибо. FYI, я пытаюсь решить немного другую проблему. Я использую LINQ для объектов/лямбда, и это работает. Я пытался преобразовать Int в String и использовать «Contains», чтобы найти соответствующие результаты -> ie db.contacts.AsEnumerable(). Где (c => c.ContactId.ToString(). Содержит (_searchitem _)). ToList(); ; – ejhost

+3

Если вы вызываете 'AsEnumerable', вы будете платить высокую цену за большие базы данных, потому что это принесет все в памяти. 'IEnumerable' медленнее по сравнению с' IQueryable', потому что позже выполняется исключительно в базе данных. – CodeArtist

+0

Да, правильно с вами – Mohammadreza

1

Использование MySql, то SqlFunctions.StringConvert не работает для меня. Поскольку я использую SelectListItem в 20+ местах в моем проекте, мне нужно решение, которое работает без искажений 20+ операторов LINQ. Мое решение состояло в подклассе SelectedListItem, чтобы обеспечить целочисленный сеттер, который перемещает преобразование типов из LINQ. Очевидно, что это решение сложно обобщить, но было весьма полезно для моего конкретного проекта.

Чтобы использовать, создайте следующий тип и используйте в своем запросе LINQ вместо SelectedListItem и используйте IntValue вместо Value.

public class BtoSelectedListItem : SelectListItem 
{ 
    public int IntValue 
    { 
     get { return string.IsNullOrEmpty(Value) ? 0 : int.Parse(Value); } 
     set { Value = value.ToString(); } 
    } 
} 
-1

Самый простой способ:

var items = from c in contacts 
      select new ListItem 
      { 
       Value = c.ContactId + "", 
       Text = c.Name 
      }; 
+0

Это кастинг c.ContactId для объекта, затем метода .ToString() вызывается. Либо одно из этих действий невозможно в linq для включения – Gh61

+0

Это невозможно в Linq для объектов? –

1

если вы используете рамки сущности и вы хотите сделать только ИНТ приемлемым, то вы можете использовать это в Linq запрос вы можете попробовать это

var items = from c in contacts 
     select new ListItem 
     { 
      Value = (int)ContractId 
      Text = c.Name 
     }; 

будет работать, потому что использование (int) будет передавать ваше значение в int, поэтому вам не нужно преобразовать строку в int, и вы получите нужный результат.

это работало для меня в моем проекте я думаю, что это будет полезно для вас ответ

+0

Я отредактировал ответ @Toby Speight, пожалуйста, проверьте ответ сейчас. –

2

Brian Cauthon превосходен! Просто небольшое обновление для EF 6, класс переместился в другое пространство имен. Поэтому, прежде чем EF 6, вы должны включать в себя:

System.Data.Objects.SqlClient 

При обновлении до EF 6, или просто используют эту версию, включают в себя:

System.Data.Entity.SqlServer 

Включив неправильное пространство имен с EF6, код будет компилироваться просто отлично, но будет вызывать ошибку времени выполнения. Надеюсь, эта заметка поможет избежать некоторой путаницы.

+0

Я должен сказать, что ваш ответ тоже отличный. Я обновился до EF6 и везде искал SqlFunctions. Ваш ответ указал мне в правильном направлении. Я просто добавлю, что вам также нужна ссылка на EntityFramework.SqlServer (у вас может быть только ссылка на EntityFramework). – Metalogic

1

еще одно решение:

c.ContactId + "" 

Просто добавьте пустую строку и он будет преобразован в строку.