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

StackOverflow https://stackoverflow.com/questions/1066760

Вопрос

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

Это было полезно?

Решение

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

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

Другие советы

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

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

Используйте LinqToObject:контакты.АсЭнумерабле()

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

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

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

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

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

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

System.Data.Objects.SqlClient

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

System.Data.Entity.SqlServer

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

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

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

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

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

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

Спасибо.

Используя 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(); }
    }
}

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

c.ContactId + ""

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

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

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

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

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

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

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

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

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

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

var items = from c in contacts
        select new ListItem
        {
            Value = Convert.ToString(c.ContactId), 
            Text = c.Name
        };
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top