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

 Shimmy28 июл. 2010 г., 00:29
Вы правы, но они также правы, они не должны переводить все функции CLR и настраиваемых функций CLR в SQL, особенно не в самой ранней версии EF :) О ToString читайте ответ Брайана: / Stackoverflow.com вопросы / 1066760 / ...
 StingyJack20 июл. 2010 г., 20:18
.ToString () также не работает для LinqToEF в VB. ИМХО, вид глупый.
 Ekaterina27 июл. 2011 г., 15:44
Отлично, а как насчет людей, использующих 3.5, а не 4? И что
 Shimmy27 июл. 2010 г., 00:21
@ StingyJack, проблема в ELINQ (сущности linq 2), потому что он переводит ваш код в SQL, а когда дело доходит до внутреннего запроса ToString, он не знает, как преобразовать ToString в SQL. В отличие от объектов linq 2, когда нет перевода, и все является лямбда-выражениями CLR, то это выполняется непосредственно для запрошенных объектов.
 StingyJack27 июл. 2010 г., 22:52
Я просто раздражен тем, что они допускают компиляцию такого рода ошибок, и что мне пришлось бесконечно троллить, чтобы найти простое английское описание причины (без юридических и научных целей).

Ответы на вопрос(15)

Решение Вопроса

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

var items = from c in contacts
            select new ListItem
            {
                Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(),
                Text = c.Name
            };
 Jeremy Coenen01 окт. 2010 г., 18:59
С какой стати они не включили перегрузку для int?
 Leo22 дек. 2016 г., 16:27
Отличный ответ! Просто обратите внимание, что, начиная с EF 6, класс переместился в другое пространство имен. Итак, перед EF 6 вы должны включить: «System.Data.Objects.SqlClient». Если вы обновляетесь до EF 6 или просто используете эту версию, включите: «System.Data.Entity.SqlServer» Включая неверное пространство имен с EF6, код скомпилируется просто отлично, но выдаст ошибку времени выполнения. Надеюсь, эта заметка поможет избежать путаницы.
 Kim Tranjan15 мар. 2012 г., 04:47
Чтобы избежать пробелов перед результатом, вы должны использоватьSqlFunctions.StringConvert((double)c.ContactId).Trim()
 OneWorld09 янв. 2013 г., 11:28
Кажется, что не работает для SQLite с использованием System.Data.SQLite Метод 'System.String StringConvert (System.Nullable`1 [System.Double])' в Typw 'System.Data.Objects.SqlClient.SqlFunctions' kann nicht in einen Speicherausdruck für 'LINQ to Entities' übersetzt werden. (не может быть переведено в «LINQ to Entities»)
 Austin08 нояб. 2011 г., 22:04
@ Nestor Это не работает для SQL Compact. Обнаружил это трудным путем.
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();
            }
        }
 Nestor01 мая 2011 г., 13:50
Да, я уже использую это. Работает для MVC3, EF4, CTP5, SQL CE4.
 Wahid Bitar26 сент. 2011 г., 23:48
Но в этом случае вы получите все данные из базы данных, а затем предположите, что вы хотите выполнить некоторую фильтрацию в этом списке доreturn list.ToList(); !!
 Shimmy30 апр. 2011 г., 23:48
Ты проверял, и это работает? читатьэт отвечай раньше.
 CmdrTallen23 июл. 2011 г., 16:21
Это выглядит более элегантно, чем боксировать вдвое и использовать StringConvert.
 Brian Cauthon27 сент. 2011 г., 21:05
Когда вы не можете получить доступ к SqlFunctions, у вас нет других вариантов, кроме этого. Тем не менее, я бы использовал это для моего запроса:return (from l in db.Customers orderby l.CompanyName select new {Id=l.CustomerID, Name=l.CompanyName}).AsEnumerable().Select(c=> new SelectListItem{Value=c.Id.ToString(), Text = c.Name}).ToList();. Делая это таким образом, только получает идентификатор / имя из базы данных (вместо всех свойств клиента) и выполняет сортировку, используя более эффективный индекс для базы данных.

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

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
};
 Craig Stuntz01 июл. 2009 г., 14:33
Нет, вы не можете использовать пользовательские свойства в LINQ to Entities (в .NET 3.5).
 Shimmy01 июл. 2009 г., 15:06
Я не проверял, но это тоже не сработает. так как это не свойство поля таблицы. Я мог бы сначала сделать это с помощью ToArray (), а затем привязать объекты, но я хочу сделать запрос к БД. Я полагаю, не сможет сделать это. Я создал свой собственный ListItem, который принимает поле int. Это работает лучше для меня.

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

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

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

контакты.AsEnumerable ()

var items = from c in contacts.AsEnumerable()
            select new ListItem
            {
                Value = c.ContactId.ToString(),
                Text = c.Name
            };
 ejhost05 дек. 2014 г., 19:49
Благодарность. К вашему сведению, я пытаюсь решить немного другую проблему. Я использую LINQ для лиц / лямбда, и это работает. Я пытался преобразовать Int в строку и использовать «Содержит», чтобы найти соответствующие результаты -> т.е. db.contacts.AsEnumerable (). Где (c => c.ContactId.ToString (). Contains Searchitem)).Составлять список(); ;
 CodeArtist26 июн. 2015 г., 21:40
Если ты позвонишьAsEnumerable Вы заплатите высокую цену за работу с большими базами данных, потому что все будет в памяти.IEnumerable медленнее по сравнению сIQueryable потому что последний выполняется исключительно в базе данных.
 Mohammadreza27 июн. 2015 г., 08:36
Да, верно с тобой

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

var items = from c in contacts
        select new ListItem
        {
            Value = Convert.ToString(c.ContactId), 
            Text = c.Name
        };
 Shimmy01 июл. 2009 г., 03:38
Нет. не работает
 G K18 июн. 2014 г., 08:05
Приведенный выше код не будет работать, так как он выдаст сообщение об ошибке, в котором говорится, что «LINQ to Entities не распознает метод метода System.String ToString (Int32)», и этот метод нельзя преобразовать в выражение хранилища. "

надеюсь, следующий код работает хорошо.

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

Благодарность

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

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

c.ContactId + ""

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

 QMaster11 авг. 2018 г., 09:20
шибка @Returned: System.NotSupportedException: Невозможно привести тип «System.Int64» к типу «System.Object». LINQ to Entities поддерживает только приведение типов примитивов и перечислений EDM.

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

класс переместился в другое пространство имен. Итак, перед EF 6 вы должны включить:

System.Data.Objects.SqlClient

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

System.Data.Entity.SqlServer

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

 Metalogic17 апр. 2017 г., 20:12
Я должен сказать, чтова Ответ тоже отлично. Я обновился до EF6 и всюду искал SqlFunctions. Ваш ответ указал мне в правильном направлении. Я просто добавлю, что вам также нужна ссылка на EntityFramework.SqlServer (у вас может быть только ссылка на EntityFramework).

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

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

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

t приемлемым, тогда вы можете использовать это в запросе linq, вы можете попробовать это

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

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

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

 Saurabh Solanki21 нояб. 2017 г., 05:26
Я отредактировал ответ @Toby Speight, пожалуйста, проверьте ответ сейчас ..
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>

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

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

 Slauma05 мар. 2013 г., 20:26
У меня не работает. Выдает исключение " ...System.String Concat(System.Object) нельзя перевести в выражение магазина ...».
 camainc03 сент. 2013 г., 21:07
У меня тоже не работает. Я также получаю «System.NotSupportedException: LINQ to Entities не распознает метод метода System.String Concat (System.Object)», и этот метод нельзя преобразовать в выражение хранилища.
 Philipp Munin25 окт. 2013 г., 19:02
НЕ РАБОТАЕТ - УДАЛИТЕ ЭТОТ ОТВЕТ [NotSupportedException: LINQ to Entities не распознает метод метода System.String Concat (System.Object), и этот метод нельзя преобразовать в выражение хранилища.]

Ваш ответ на вопрос