Проблема с преобразованием int в строку в Linq для объектов

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 неспособным привыкнуть к строгости С#!!!

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

Что я делаю, если я хочу выполнять строковые манипуляции, сначала выполните запрос в linq-to-entity, а затем обработайте stings в 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. Также имейте в виду, что с помощью этого метода возможно ограничение производительности.

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

System.Data.Objects.SqlClient

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

System.Data.Entity.SqlServer

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

Ответ 8

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

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

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

Ответ 9

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

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

Спасибо.

Ответ 10

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

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

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

Ответ 11

если вы используете инфраструктуру сущности и хотите сделать единственное int приемлемым, тогда вы можете использовать это в запросе linq, вы можете попробовать это

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

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

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

Ответ 12

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

c.ContactId + ""

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

Ответ 13

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

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

Ответ 14

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

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
};

Ответ 15

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>

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

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

Ответ 16

Можете ли вы попробовать:

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