2009-06-26 4 views
2

LINQ 쿼리의 XmlNode에서 "InnerText"속성을 호출하면 "같은 키를 가진 항목이 이미 추가되었습니다."라는 이상한 오류가 발생합니다.LINQ 쿼리의 XmlNode에서 "InnerText"가 작동하지 않습니다.

쿼리 보이는 같은 :

var partnersXml = from partnerTable in dataContext.SomeTableInDb 
        where partnerTable.XmlType == "partner" 
        select new 
        { 
        partnerId = XmlDocumentWrapper(partnerTable.XmlDocument).SelectSingleNode("//*[name()='partnerId']").InnerText     
        }; 

설명 :

  • partnerTable.XmlDocument
  • XmlDocumentWrapper이 방법은 주어진 XML 문자열을위한을 XmlDocument를 반환 DB에 문자열 XML은

"InnerText"없이 쿼리가 완벽하게 작동합니다 (partnerId에 XmlNode가 포함됨). LINQ에서 이런 종류의 버그가 있습니까? 이 문제의 해결 방법은 무엇입니까?

스택 추적 :

System.ArgumentException : 동일한 키 가진 항목이 이미 추가되었습니다. System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add) at System.Data.Linq.Mapping.UnmappedType.GetDataMember(MemberInfo mi) at System.Data.Linq.SqlClient.SqlFactory.Member(SqlExpression expr, MemberInfo member) at System.Data.Linq.SqlClient.QueryConverter.VisitMemberAccess(MemberExpression ma) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) at System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) at System.Data.Linq.SqlClient.QueryConverter.VisitNew(NewExpression qn) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node) at System.Data.Linq.SqlClient.QueryConverter.VisitSelect(Expression sequence, LambdaExpression selector) at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc) at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node) at System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node) at System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations) at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) at System.Data.Linq.DataQuery 1.System.Collections.Generic.IEnumerable.GetEnumerator() 그것은 SQL에 LINQ처럼 보이는

+0

어떤 stacktrace? 어떤 그룹화를하고 있습니까? 뚜렷한? 사전 어딘가에 관련되어있는 것처럼 들리네 ... –

+0

그룹화가 없거나 뚜렷하지 않습니다. 내가받는 유일한 메시지는 "동일한 키를 가진 항목이 이미 추가되었습니다."입니다. –

답변

2

에서 System.ThrowHelper.ThrowArgumentException (ExceptionResource 자원) 에서 어떤 일을하려고한다 매핑하는 반면 .NET 측에서 수행되기를 원합니다. (나는 데이터베이스가 XPath를 수행하기를 원한다면 나는 두려워하지 않는다고 생각한다.) 다음을 시도해 보라. 이것을보십시오 :

var partnersXml = dataContext.SomeTableInDb 
    .Where(x => x.XmlType == "partner") 
    .AsEnumerable() // This forces the rest of the query to be done in the CLR 
    .Select(x => new { 
      partnerId = XmlDocumentWrapper(x.XmlDocument) 
          .SelectSingleNode("//*[name()='partnerId']") 
          .InnerText 
    }); 
+0

존, 멋진 솔루션. 나는 당신에게 런던의 StackOverflow Dev Days에서 맥주를 ​​사줄 것이다. :) 키는 ".AsEnumerable()"이며 람다 식으로이 쿼리를 수행 할 필요는 없습니다. dataContext.SomeTableInDb.AsEnumerable() -의 partnerTable과 마찬가지로 수행 할 수 있습니다. –

+0

"Where"절이 SQL에서 실행되기를 원하지 않습니까? SQL에서 수행 할 쿼리의 양과 CLR에서 수행 할 작업의 양을 결정해야합니다. –

+0

네, 그렇습니다.하지만 람다가 아닌 쿼리를 원한다면이 문제를 해결하는 방법을 설명해 드리겠습니다. 그러나 SQL에서 where 절을 실행하면 거의 항상 더 나은 아이디어 (성능)가 완벽한 람다 솔루션입니다. –

관련 문제