2016-12-07 6 views
1

Ich versuche, eine SQL-Abfrage mit EF excrimestorequery auszuführen.EF excrimestorequery wirft Ausnahme über - Konvertierung fehlgeschlagen beim Konvertieren des Varchar-Wertes '30267-366492' in den Datentyp int

Die Repository-Methode, die die Abfrage ausführt, ist wie folgt. Es nimmt eine Liste von Tupeln (studentid, sectionid) und erstellt eine Zeichenfolge von studentid-sectionid-Werten, die der Eingabeparameter für die Abfrage ist.

public static List<EF.TraditionalGradingEntity> GetTraditionalGrading(List<Tuple<int, int>> studentSectionIds) 
{ 
    List<string> tempList = new List<string>(); 
    foreach (Tuple<int, int> studentSectionId in studentSectionIds) 
    { 
     tempList.Add(studentSectionId.Item1.ToString() + "-" + studentSectionId.Item2.ToString()); 
    } 
    string stuSecIds = string.Join(",", tempList.ToArray()); 
    string strTdlGradingQuery = string.Format(
     @" 
     select 
      tbgTraj.studentPersonID, 
      tbgTraj.sectionID, 
      tbgTraj.studentPersonID_SectionID, 
      tbgTraj.score, 
      tbgTraj.sel, 
      tbgTraj.growth, 
      tbgTraj.warning, 
      tbgTraj.taskID, 
      tbgTraj.gradingTask, 
      tbgTraj.taskScore, 
      tbgScore.groupName, 
      tbgScore.activityName, 
      tbgScore.score activityScore 
     from 
      [shs].[DataCollector_TBG_Grade_Trajectory] tbgTraj 
      inner join [shs].[DataCollector_TBG_Scores] tbgScore 
       on tbgTraj.taskID = tbgScore.taskID 
       and tbgTraj.studentPersonID = tbgScore.studentPersonID 
       and tbgTraj.sectionID = tbgScore.sectionID 
     where 
      tbgTraj.studentPersonID_SectionID in ({0}) 
     ", stuSecIds); 

    using (EF.AESDBContext aesDBContext = new EF.AESDBContext()) 
    { 
     return aesDBContext.ObjectContext.ExecuteStoreQuery<EF.TraditionalGradingEntity>(strTdlGradingQuery, "TraditionalGradings", MergeOption.OverwriteChanges, null).ToList(); 
    } 
} 

Meine Entitätsdefinition ist als

public class TraditionalGradingEntity 
{ 
    public int StudentPersonId { get; set; } 
    public int SectionId { get; set; } 
    public string StudentPersonID_SectionID { get; set; } 
    public string Score { get; set; } 
    public string Sel { get; set; } 
    public string Growth { get; set; } 
    public string Warning { get; set; } 
    public int TaskId { get; set; } 
    public string GradingTask { get; set; } 
    public string TaskScore { get; set; } 
    public string GroupName { get; set; } 
    public string ActivityName { get; set; } 
    public string ActivityScore { get; set; } 
} 

Nun folgt, unabhängig von dem Eingangsparameterwert, die Ausführung nicht immer mit folgenden Ausnahme:

System.Data.EntityCommandExecutionException was unhandled by user code 
    HResult=-2146232004 
    Message=An error occurred while reading from the store provider's data reader. See the inner exception for details. 
    Source=System.Data.Entity 
    StackTrace: 
     at System.Data.Common.Internal.Materialization.Shaper`1.StoreRead() 
     at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext() 
     at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
     at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 
     at D125Portal.DA.EbrRepository.GetTraditionalGrading(List`1 studentSectionIds) in C:\Users\rgopinathan\Source\Workspaces\Workspace_D125New\EBRLevel\D125Portal\D125Portal.DataAccess\EbrRepository.cs:line 218 
     at D125Portal.BL.EBR.ReportS.Init() in C:\Users\rgopinathan\Source\Workspaces\Workspace_D125New\EBRLevel\D125Portal\D125Portal.BL\EBR\ReportS.cs:line 73 
     at D125Portal.BL.EBR.ReportManager.GetReport(ReportRequestS req) in C:\Users\rgopinathan\Source\Workspaces\Workspace_D125New\EBRLevel\D125Portal\D125Portal.BL\EBR\Report.cs:line 79 
     at D125Portal.WWW.Areas.EBR.Coordinator.GetStudentReport(List`1 students) in C:\Users\rgopinathan\Source\Workspaces\Workspace_D125New\EBRLevel\D125Portal\D125Portal\Areas\EBR\Coordinator.cs:line 106 
     at D125Portal.WWW.Areas.EBR.Controllers.EBRHomeController.Report() in C:\Users\rgopinathan\Source\Workspaces\Workspace_D125New\EBRLevel\D125Portal\D125Portal\Areas\EBR\Controllers\EBRHomeController.cs:line 164 
     at lambda_method(Closure , ControllerBase , Object[]) 
     at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) 
     at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
     at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
     at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) 
     at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) 
     at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End() 
     at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) 
     at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d() 
     at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() 
    InnerException: System.Data.SqlClient.SqlException 
     HResult=-2146232060 
     Message=Conversion failed when converting the varchar value '30267-366492' to data type int. 
     Source=.Net SqlClient Data Provider 
     ErrorCode=-2146232060 
     Class=16 
     LineNumber=2 
     Number=245 
     Procedure="" 
     Server=ovdcovyjrr.database.windows.net 
     State=1 
     StackTrace: 
      at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
      at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
      at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
      at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
      at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows) 
      at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more) 
      at System.Data.SqlClient.SqlDataReader.Read() 
      at System.Data.Common.Internal.Materialization.Shaper`1.StoreRead() 
     InnerException: 

Hinweis: Der Wert ' 30267-366492 'in der Ausnahmebedingungsnachricht ist immer gleich, unabhängig vom Eingangsparameterwert und den Ausgangsdaten (auch wenn der Ausgang diesen Wert nicht enthält). Ich bin in der Lage, die Abfrage separat erfolgreich auszuführen, aber nicht über das Programm. Jede Einsicht oder Hilfe wird sehr geschätzt.

+1

Sie haben vergessen, einfache Anführungszeichen um die Werte zu setzen, die Sie zusammenfügen und in Ihre Abfrage formatieren. – juharr

+0

Ja, danke. Das hat geholfen. Da die Ausnahme einen bestimmten Wert aufwies ('30267-366492'), war ich so abgelenkt, dass ich sie ausgewählt hatte und wiederholte auch immer nur die Zuordnung der Entity-Klasse, um sicherzustellen, dass die Datentypen korrekt zugewiesen waren. – Raj

Antwort

0
tempList.Add(studentSectionId.Item1.ToString() + "-" + studentSectionId.Item2.ToString()) 
... 
string stuSecIds = string.Join(",", tempList.ToArray()); 

Hier sind Sie vermutlich ganze Zahlen in einer Weise verketten, dass so etwas ähneln würde: 0-3, 1-4, 2-5. Also im Großen und Ganzen ist Ihre Where-Klausel: where tbgTraj.studentPersonID_SectionID in (-3, -3, -3). Beachten Sie, dass diese integers sind, da die - als eine Subtraktion interpretiert wird. In Ihrem tbgTraj.studentPersonID_SectionID haben Sie den Wert '30267-366492', der nicht zu einem int konvertieren wird. SQL Server versucht, es implizit in eine int zu konvertieren, da in einem Vergleich string = int, int Vorrang hat (see here).

So würde Ihre Lösung Anführungszeichen verwenden, um Ihre ids:

"'" + studentSectionId.Item1.ToString() + "-" + + studentSectionId.Item2.ToString() "'" ... 

Auch passen sie von bobby tables. Sie sollten Ihre Abfragen parametrisieren, um eine SQL-Injektion zu vermeiden!

+0

Danke. Obwohl die Subtraktion nicht stattfand (wie ich die ToString() hatte), half das Hinzufügen der einfachen Anführungszeichen um die ID-Paare, die Ausnahme zu überwinden. – Raj

+0

Die Subtraktion erfolgte in der SQL-Interpretation. Froh, dass es geholfen hat – HoneyBadger

0

Stellen Sie sicher, dass Sie die Liste der ID-Paare in einfache Anführungszeichen setzen, damit Sie studentPersonID_SectionID mit einer Reihe von Zeichenfolgen anstelle einer Menge Ganzzahlen vergleichen (die Zahlen werden in SQL subtrahiert).

tempList.Add(string.Format(
    "'{0}-{1}'", 
    studentSectionId.Item1, 
    studentSectionId.Item2)); 
+0

Danke. Obwohl die Subtraktion nicht stattfand (wie ich die ToString() hatte), half das Hinzufügen der einfachen Anführungszeichen um die ID-Paare, die Ausnahme zu überwinden. – Raj

+0

Was ich mit Subtraktion meinte, ist, dass Sie etwas wie 'In (30267-366492)' in der SQL-Abfrage haben und es würde etwas wie 'In (-336225)' ergeben, weil der SQL-Server '30267-366492' als behandeln würde eine Subtraktion. – juharr

+0

Ah, ok. Hab dich. Danke für die Antworten, schätze deine Hilfe. – Raj

Verwandte Themen