EF executestorequery抛出异常 - 转换varchar值时转换失败' 30267-366492'到数据类型int

时间:2016-12-07 18:09:04

标签: c# sql asp.net-mvc entity-framework

我尝试使用EF executestorequery执行sql查询。

执行查询的存储库方法如下。它需要一个元组列表(studentid,sectionid)并构造一个studentid-sectionid值字符串,这是查询的输入参数。

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

我的实体定义如下

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

现在,无论输入参数值如何,执行总是失败,并出现以下异常:

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: 

注意:值&#39; 30267-366492&#39;在异常消息中始终是相同的,与输入参数值和输出数据无关(即使输出不包含该值)。我能够单独成功运行查询,但不能通过程序运行。任何见解或帮助都非常感谢。

2 个答案:

答案 0 :(得分:0)

确保在id对列表周围放置单引号,以便将studentPersonID_SectionID与一组字符串而不是一组整数进行比较(数字将最终在SQL中减去)。

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

答案 1 :(得分:0)

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Grid example")
        grid = Gtk.Grid()

        #combobox
        devices_list = Gtk.ListStore(int, str)
        devices_list.append([1, "Device 1"])
        devices_list.append([2, "Device 2"])
        name_combo = Gtk.ComboBox.new_with_model_and_entry(devices_list)
        *name_combo.connect("changed", self.on_name_combo_changed)*
        name_combo.set_entry_text_column(1)
        grid.attach(name_combo, 5, 0, 2, 1)

在这里,你可能会以类似于tempList.Add(studentSectionId.Item1.ToString() + "-" + studentSectionId.Item2.ToString()) ... string stuSecIds = string.Join(",", tempList.ToArray()); 之类的方式连接整数。所以整个你的where子句是:0-3, 1-4, 2-5。请注意,这些是where tbgTraj.studentPersonID_SectionID in (-3, -3, -3),因为integers被解释为减法。在-中,您获得的值tbgTraj.studentPersonID_SectionID不会转换为'30267-366492'。 SQL服务器尝试将其隐式转换为int,因为在比较int中,string = int优先(see here)。

所以你的解决方案就是在id周围使用引号:

int

另外,请注意bobby tables。您应该参数化您的查询以避免sql注入!