2016-08-09 3 views
0

다음 오류가 발생하지만 내 성명을 다시 쓰는 방법을 모르십니까? 아이디어가 있으십니까?Entity Framework - 문자열 변환 오류

오류 :

LINQ to Entities does not recognize the method 'System.String Convert(System.String)' method, and this method cannot be translated into a store expression

코드 :

public Client FindClientByMobile(string mobile, string accountId) 
{ 
    Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted 
      && ((Convert(c.TelephoneHome) == mobile) || (Convert(c.TelephoneMobile) == mobile) || (Convert(c.TelephoneWork) == mobile))); 
    return client; 
} 

public static string Convert(string mobile) 
{ 
    var filterNumber = from letter in mobile 
         where char.IsDigit(letter) 
         select letter; 

    StringBuilder number = new StringBuilder(); 
    number.Append(filterNumber.ToArray()); 

    return number.ToString(); 
} 
+2

이 오류는 Linq가 표현을 Sql 문으로 변환해야 함을 의미합니다. 커스텀'Convert' 메쏘드는 데이터베이스 서버에 존재하는 것이 아니라 C# 코드이기 때문에 번역 할 수 없습니다. – Igor

+0

안녕하세요, 고맙지 만 이미 문제를 언급했지만 질문했지만 문안을 다시 작성하는 방법을 모르십니까? –

+0

전화 번호가 문자열에 있습니다 –

답변

4

오류가 Linq는이 SQL 문을로 표현을 번역 할 필요가 있다는 것을 의미한다. 사용자 지정 Convert 메서드는 데이터베이스 서버에도 존재하는 C# 코드가 아니기 때문에 변환 할 수 없습니다.

계정 ID를 이미 전달하고 있으므로 고유 한 것으로 가정하거나 많은 수의 개체를 검색하지 않도록 고유 한 위치에 충분히 필터링 할 것으로 가정합니다. 그런 다음 개체 그래프를 먼저 구체화 한 다음 C# (linq 및 개체)에서 더 많이 필터링 할 수 있습니다. 이것은 ToList() 호출을 사용하여 수행됩니다.

public Client FindClientByMobile(string mobile, string accountId) 
{ 
    var clients = RepositorySet.Include("Account").Where(c => c.AccountId == accountId && !c.IsDeleted).ToList(); 
    return clients.FirstOrDefault(client => Convert(client.TelephoneHome) == mobile || Convert(client.TelephoneMobile) == mobile || Convert(client.TelephoneWork) == mobile); 
} 
+0

이것은 꽤 똑똑합니다. 좋은 장소! –

1

당신도 또한 () 같은 다른 문자를 대체 할 수 Replace를 사용하여 귀하의 코멘트

@Imad, what im trying to do is validate, so if the number has been stored in the database as 0331-9000-100, I want to remove all non numeric characters, mobile has already had this applied, so mobile = 033319000100

public Client FindClientByMobile(string mobile, string accountId) 
{ 
    Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted 
      && ((c.TelephoneHome.Replace("-","") == mobile) || (Convert(c.TelephoneMobile) == mobile) || (Convert(c.TelephoneWork) == mobile))); 
    return client; 
} 

에서 언급 한 바와 같이이 당신을 맞는 않습니다.

기억할 점 : Replace(char, char)은 작동하지 않지만 Replace(string, string)이됩니다.

0

첫 번째 문제는 Convert 호출이 C#이며 SQL로 변환 할 수 없다는 것입니다. 모든 함수가 할 수있는 것은 아니지만 일부 (예를 들어 하위 문자열)는 Entity Framework에 '알려진'것이며이를 적절한 SQL로 변환 할 수 있습니다. 따라서 EF가 인식하는 문자열 함수를 사용하기 위해 구문을 다시 작성하거나 논리를 다른 방식으로 데이터베이스로 푸시해야합니다.

@Imad 이미 EF 알려진입니다 string.Replace를 사용하여 제안했지만, 물론 당신이 모든 가능한 숫자가 아닌 문자를 제거하는 데 도움 않을거야 - 당신이 명시 적으로 코딩하는 유일한 사람처럼 '-'를, 'extension'과 같은 다른 알파 문자열은 사용할 수 없습니다.

빠른 속도로 만들고 싶다면 별도의 필드에 '청소'번호를 저장하는 것이 좋습니다. 그러면 쿼리는

Client client = RepositorySet.Include("Account").FirstOrDefault(c => c.AccountId == accountId && !c.IsDeleted 
     && (c.TelephoneHomeClean == mobile) || (c.TelephoneMobileClean == mobile) || (c.TelephoneWorkClean == mobile))); 
return client; 

이되며 훨씬 빠르게 만들고 색인을 생성 할 수 있습니다.

+0

데이터를 감사/업데이트하기 위해 SP를 작성해야하므로 장기적인 관점에서 좋은 아이디어입니다. –

+0

그래, 네가 원하는 것보다 훨씬 성가신 노력이야. –

관련 문제