Linq에서 int를 문자열로 변환하는 데 문제가 있습니다.


202
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 #의 엄격성에 익숙해 질 수 없습니다!


2
VB의 LinqToEF에서도 .ToString ()이 작동하지 않습니다. IMHO, 멍청한 종류.
StingyJack

5
@StingyJack에서 문제는 코드를 SQL로 변환하고 내부 ToString 요청과 관련하여 'ToString'을 SQL로 변환하는 방법을 모르기 때문에 ELINQ (linq 2 엔티티)의 문제입니다. linq 2 객체와 달리 변환이없고 모든 것이 CLR 람다 인 경우 요청 된 객체에서 직접 수행됩니다.
Shimmy Weitzhandler

1
나는 그것들이 그런 종류의 오류가 컴파일되도록 허용하고, 원인에 대한 명확한 영어 설명을 찾기 위해 영원히 트롤을해야한다고 화나게했습니다 (법률과 학계).
StingyJack

1
당신 말이 맞지만, 그들은 또한 맞습니다. 모든 CLR 및 맞춤형 CLR 기능을 SQL로 변환하지 않아야합니다. 특히 초기 버전의 EF에서는 그렇지 않습니다.) ToString에 대해 Brian의 답변 : stackoverflow를
Shimmy Weitzhandler

훌륭하지만 3.5를 사용하는 사람들은 어떻습니까? 그리고 뭐?
예카테리나

답변:


313

EF v4에서는을 사용할 수 있습니다 SqlFunctions.StringConvert. int에 대한 과부하가 없으므로 두 배 또는 소수로 캐스트해야합니다. 코드는 다음과 같이 보입니다.

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

234
왜 지구상에서 그들은 int에 대한 과부하를 포함하지 않습니까?
Jeremy Coenen

7
@Nestor SQL Compact에서는 작동하지 않습니다. 어려운 길을 찾았습니다.
Austin

24
결과 전에 공백을 피하려면 다음을 사용해야합니다.SqlFunctions.StringConvert((double)c.ContactId).Trim()
Kim Tranjan

2
System.Data.SQLite를 사용하여 SQLite에서 작동하지 않는 것 같습니다. 'LINQ to Entities'에 대해 자세히 알아보십시오. ( "LINQ to Entities"로 번역 될 수 없음)
OneWorld

5
훌륭한 답변! EF 6을 사용하기 시작하면 클래스가 다른 네임 스페이스로 옮겨졌습니다. 따라서 EF 6 이전에는 "System.Data.Objects.SqlClient"를 포함해야합니다. EF 6으로 업데이트하거나이 버전을 사용하는 경우 다음을 포함하십시오. "System.Data.Entity.SqlServer"잘못된 네임 스페이스를 포함하여 EF6, 코드는 정상적으로 컴파일되지만 런타임 오류가 발생합니다. 이 노트가 혼란을 피하는 데 도움이되기를 바랍니다.
Leo

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

이것은 그것을 해결하는 한 가지 방법이지만, 만약 이것이 많은 양의 객체를 가지고 있다면이 foreach는 과도합니다 ...
Serlok

9

LinqToObject : 연락처를 사용하십시오. AsEnumerable ()

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

감사. 참고로, 약간 다른 문제를 해결하려고합니다. 엔티티 / 람다에 LINQ를 사용하고 있으며 작동합니다. 내가 일치하는 결과를 찾을 문자열 및 사용에 int를 변환 "포함합니다"시도하고 있었다 -.> 즉 db.contacts.AsEnumerable () 경우 (. C => c.ContactId.ToString () 포함 ( searchitem .)) ToList (); ;
ejhost

9
전화 AsEnumerable하면 모든 것이 메모리에 저장되므로 더 큰 데이터베이스에서는 고성능 가격을 지불하게됩니다. 후자는 데이터베이스에서 독점적으로 실행되기 때문에 IEnumerable속도가 느립니다 IQueryable.
CodeArtist

5

SqlFunctions.StringConvert는 작동하지만 번거롭고 대부분 SQL 측에서 문자열 변환을 수행 할 필요가 없습니다.

문자열 조작을 수행하려면 먼저 linq-to-entities에서 쿼리를 수행 한 다음 linq-to-objects에서 찌르기를 조작해야합니다. 이 예에서는 Contact의 전체 이름과 ContactLocationKey (ContactID 및 LocationID)의 문자열 연결 인 ContactLocationKey를 포함하는 데이터 세트를 가져 오려고합니다.

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

당신은 그것을 테스트하고 작동합니까? 답변을 전에 읽으십시오 .
Shimmy Weitzhandler

예, 이미 사용하고 있습니다. MVC3, EF4, CTP5, SQL CE4에서 작동합니다.
Nestor

이것은 복싱과 StringConvert를 사용하는 것보다 더 우아합니다.
CmdrTallen

9
그러나이 경우 데이터베이스에서 모든 데이터를 가져 와서 이전 에이 목록에서 필터링을 원한다고 가정하십시오 return list.ToList();!!
Wahid Bitar

4
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();. 이 방법을 사용하면 모든 고객 속성 대신 db에서 id / name 만 가져오고 db에서보다 효율적인 색인을 사용하여 정렬합니다.
Brian Cauthon

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

먼저 객체로 변환하면 toString ()이 정확합니다.


3

Brian Cauthon의 답변은 훌륭합니다! EF 6의 경우 약간의 업데이트만으로 클래스가 다른 네임 스페이스로 이동했습니다. 따라서 EF 6 이전에는 다음을 포함해야합니다.

System.Data.Objects.SqlClient

EF 6으로 업데이트하거나이 버전을 사용중인 경우 다음을 포함하십시오.

System.Data.Entity.SqlServer

EF6에 잘못된 네임 스페이스를 포함 시키면 코드가 정상적으로 컴파일되지만 런타임 오류가 발생합니다. 이 노트가 혼란을 피하는 데 도움이되기를 바랍니다.


당신의 대답도 훌륭 하다고 말해야합니다 . 나는 EF6로 업그레이드하고 SqlFunctions를 찾아 어디에서나 찾고 있습니다. 당신의 대답은 올바른 방향으로 나를 가리 켰습니다. EntityFramework.SqlServer에 대한 참조가 필요하다고 추가합니다 (EntityFramework에 대한 참조 만있을 수 있음).
Metalogic

2

MVC 2 앱을 MVC 3으로 변환 할 때이 동일한 문제가 발생 하여이 문제에 대한 다른 (깨끗한) 솔루션을 제공하기 위해 내가 한 일을 게시하고 싶습니다 ...

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

GetProducers ()는 단순히 생산자의 엔터티 컬렉션을 반환합니다. 추신 : SqlFunctions.StringConvert가 작동하지 않았습니다.


2

"연락처"가 일반 목록으로 작동하는 경우 다음 코드가 제대로 작동하기를 바랍니다.

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

감사.


2

하나 더 해결책 :

c.ContactId + ""

빈 문자열을 추가하면 문자열로 변환됩니다.


반환 된 오류 : System.NotSupportedException : 'System.Int64'형식을 'System.Object'형식으로 캐스팅 할 수 없습니다. LINQ to Entities는 EDM 기본 또는 열거 유형의 캐스팅 만 지원합니다.
QMaster

1

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

1

엔티티 프레임 워크를 사용하고 유일하게 int를 허용하려면 linq 쿼리에서 이것을 사용할 수 있습니다.

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

(int)를 사용하면 값을 int로 캐스팅하므로 string을 int로 변환 할 필요가 없으므로 원하는 결과를 얻을 수 있기 때문에 작동합니다.

이것은 내 프로젝트에서 나를 위해 일한 것이 당신에게 도움이 될 것이라고 생각합니다.


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

아니요. LINQ to Entities (.NET 3.5)에서는 사용자 지정 속성을 사용할 수 없습니다.
Craig Stuntz

1
테스트하지는 않았지만 작동하지 않습니다. 테이블 필드 속성이 아니기 때문입니다. 먼저 ToArray ()를 사용하여 객체를 링킹 할 수는 있지만 DB를 쿼리하고 싶습니다. 나는 그것을 할 수 없을 것이라고 생각합니다. int 필드를 사용하는 자체 ListItem을 만들었습니다. 그것은 나를 위해 더 잘 작동합니다.
Shimmy Weitzhandler

-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)'메소드를 인식하지 못하므로이 메소드를 상점 표현식으로 변환 할 수 없습니다.]
Philipp Munin

-6

할 수 있겠 니:

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

위 코드는 "LINQ to Entities가 'System.String ToString (Int32)'메소드를 인식하지 못해이 메소드를 상점 표현식으로 변환 할 수 없습니다."라는 오류를 표시하므로 작동하지 않습니다.
GK
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.