Проблема с преобразованием 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
};