【问题标题】:Filter FormView by Query String按查询字符串过滤 FormView
【发布时间】:2013-03-11 20:41:04
【问题描述】:

我有一个连接到 LinqDataSource 的 FormView,我想按查询字符串进行过滤。基本上,如果通过查询字符串传入 ID,我只想显示该记录,否则如果没有提供 ID,则将它们全部显示。我已经设法使用几种不同的方法使其工作,但是每次我尝试将数据保存在 FormView 中时,我都会遇到异常:Operator '==' incompatible with operand types 'Int32?' and 'Object'。

当我调用FormView.UpdateItem(true) 时,会引发上述异常。以下是我过滤 LinqDataSource 的方法:

protected void ldsIncidents_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    if (!String.IsNullOrEmpty(Request.QueryString["id"]))
    {
        e.Result = db.Incidents.Where(i => i.Incident_Number == Convert.ToInt32(Request.QueryString["id"]));
    }
}

当我调用FormView.UpdateItem(true) 时抛出异常。一旦我从上面的Selecting 事件中删除代码,一切正常,但我无法再过滤数据。我也尝试将 WhereParameters 动态添加到 LinqDataSource,但同样的事情发生了。有谁知道为什么会发生这种情况或如何解决它?如果有帮助,这是我的堆栈跟踪:

Exception Type: System.Web.Query.Dynamic.ParseException
Message: Operator '==' incompatible with operand types 'Int32?' and 'Object'
Stack Trace:
   at System.Web.Query.Dynamic.ExpressionParser.CheckAndPromoteOperands(Type signatures, String opName, Expression& left, Expression& right, Int32 errorPos)
   at System.Web.Query.Dynamic.ExpressionParser.ParseComparison()
   at System.Web.Query.Dynamic.ExpressionParser.ParseLogicalAnd()
   at System.Web.Query.Dynamic.ExpressionParser.ParseLogicalOr()
   at System.Web.Query.Dynamic.ExpressionParser.ParseExpression()
   at System.Web.Query.Dynamic.ExpressionParser.Parse(Type resultType)
   at System.Web.Query.Dynamic.DynamicExpression.ParseLambda(ParameterExpression[] parameters, Type resultType, String expression, Object[] values)
   at System.Web.Query.Dynamic.DynamicExpression.ParseLambda(Type itType, Type resultType, String expression, Object[] values)
   at System.Web.Query.Dynamic.DynamicQueryable.Where(IQueryable source, String predicate, Object[] values)
   at System.Web.UI.WebControls.DynamicQueryableWrapper.Where(IQueryable source, String predicate, Object[] values)
   at System.Web.UI.WebControls.QueryableDataSourceView.ExecuteQueryExpressions(IQueryable source, QueryContext context)
   at System.Web.UI.WebControls.QueryableDataSourceView.ExecuteQuery(IQueryable source, QueryContext context)
   at System.Web.UI.WebControls.LinqDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments)
   at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback)
   at System.Web.UI.WebControls.DataBoundControl.PerformSelect()
   at System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
   at System.Web.UI.WebControls.GridView.DataBind()
   at System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound()
   at System.Web.UI.WebControls.CompositeDataBoundControl.CreateChildControls()
   at System.Web.UI.Control.EnsureChildControls()
   at System.Web.UI.WebControls.CompositeDataBoundControl.get_Controls()
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.DataBoundControlHelper.ExtractValuesFromBindableControls(IOrderedDictionary dictionary, Control container)
   at System.Web.UI.WebControls.FormView.ExtractRowValues(IOrderedDictionary fieldValues, Boolean includeKeys)
   at System.Web.UI.WebControls.FormView.HandleUpdate(String commandArg, Boolean causesValidation)
   at System.Web.UI.WebControls.FormView.UpdateItem(Boolean causesValidation)
   at PRIDE.Pages.Incidents.View.btnSaveIncident_Click(Object sender, EventArgs e) in C:\Users\hopfnejo\Documents\Development Projects\PRIDE\PRIDE\Pages\Incidents\View.aspx.cs:line 317

编辑

这里是FormView的ItemUpdating事件的内容:

protected void fvIncident_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
    TabContainer tc = fvIncident.FindControl("tcMain") as TabContainer;

    e.NewValues["Division"] = (tc.Tabs[0].FindControl("cboDivision") as DropDownList).SelectedValue;
    e.NewValues["Safety"] = (tc.Tabs[0].FindControl("chkSafety") as CheckBox).Checked;
    e.NewValues["Quality"] = (tc.Tabs[0].FindControl("chkQuality") as CheckBox).Checked;
    e.NewValues["Cost"] = (tc.Tabs[0].FindControl("chkCost") as CheckBox).Checked;
    e.NewValues["Production"] = (tc.Tabs[0].FindControl("chkProduction") as CheckBox).Checked;
    e.NewValues["Environment"] = (tc.Tabs[0].FindControl("chkEnvironment") as CheckBox).Checked;
    e.NewValues["Department"] = (tc.Tabs[0].FindControl("cboDepartment") as DropDownList).SelectedValue;
    e.NewValues["Area"] = (tc.Tabs[0].FindControl("cboArea") as DropDownList).SelectedValue;
    e.NewValues["Initiated_By"] = (tc.Tabs[0].FindControl("txtInitiatedBy") as TextBox).Text;
    e.NewValues["KRA_Notes"] = (tc.Tabs[0].FindControl("txtKRANotes") as TextBox).Text;
    e.NewValues["Incident_type"] = (tc.Tabs[0].FindControl("cboIncidentType") as DropDownList).SelectedValue;
    e.NewValues["Aspect_Affected"] = (tc.Tabs[0].FindControl("cboAspectAffected") as DropDownList).SelectedValue;

    e.NewValues["Incident_Level"] = (tc.Tabs[1].FindControl("cboIncidentLevel") as DropDownList).SelectedValue;
    e.NewValues["ADM_Testing_Within_Guidelines"] = (tc.Tabs[1].FindControl("chkADMTestingWithinGuidelines") as CheckBox).Checked;
    e.NewValues["ADM_Testing_Required"] = (tc.Tabs[1].FindControl("chkADMTestingRequired") as CheckBox).Checked;
    e.NewValues["Number_Of_People_Involved"] = (tc.Tabs[1].FindControl("txtNumPeopleInvolved") as TextBox).Text;

    e.NewValues["Mill_State"] = (tc.Tabs[2].FindControl("cboMillState") as DropDownList).SelectedValue;
    e.NewValues["Area_Downtime"] = (tc.Tabs[2].FindControl("txtDowntime") as TextBox).Text;
    e.NewValues["Production_Amount_Lost"] = (tc.Tabs[2].FindControl("txtProductionAmountLost") as TextBox).Text;
    e.NewValues["Production_Actual_or_Estimate"] = (tc.Tabs[2].FindControl("cboProductionActualOrEstimate") as DropDownList).SelectedValue;
    e.NewValues["Production_Units"] = (tc.Tabs[2].FindControl("cboProductionUnits") as DropDownList).SelectedValue;

    e.NewValues["Environmental_Impact"] = (tc.Tabs[3].FindControl("txtEnvironmentalImpact") as TextBox).Text;
    e.NewValues["Environmental_Specialist_Notified"] = (tc.Tabs[3].FindControl("cboEnvironmentalSpecialistNotified") as DropDownList).SelectedValue;
    e.NewValues["Environmental_Incident_Reportable_to_Government"] = (tc.Tabs[3].FindControl("cboEnvironmentalIncidentReportableToGovernment") as DropDownList).SelectedValue;
    e.NewValues["Environmental_Governement_Agency_Involved"] = (tc.Tabs[3].FindControl("txtGovernmentAgencyInvolved") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[3].FindControl("txtDateReported") as TextBox).Text))
        e.NewValues["Environmental_Date_Reported"] = null;
    else
        e.NewValues["Environmental_Date_Reported"] = (tc.Tabs[3].FindControl("txtDateReported") as TextBox).Text;
    e.NewValues["Environmental_Action_Taken"] = (tc.Tabs[3].FindControl("txtEnforcementActionTaken") as TextBox).Text;
    e.NewValues["Environmental_Reference_Number"] = (tc.Tabs[3].FindControl("txtReferenceNumber") as TextBox).Text;

    e.NewValues["Procedures"] = (tc.Tabs[4].FindControl("txtProceduresAffected") as TextBox).Text;
    e.NewValues["Referances"] = (tc.Tabs[4].FindControl("txtReferences") as TextBox).Text;

    e.NewValues["Reviewed_By__BUL_"] = (tc.Tabs[8].FindControl("txtReviewedByBUL") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtSignOffDateBUL") as TextBox).Text))
        e.NewValues["Sign_Off_Date__BUL_"] = null;
    else
        e.NewValues["Sign_Off_Date__BUL_"] = (tc.Tabs[8].FindControl("txtSignOffDateBUL") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtPlannedReviewDate") as TextBox).Text))
        e.NewValues["Planned_Review_Date"] = null;
    else
        e.NewValues["Planned_Review_Date"] = (tc.Tabs[8].FindControl("txtPlannedReviewDate") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtPlannedCompletionDate") as TextBox).Text))
        e.NewValues["Planned_Completion_Date"] = null;
    else
        e.NewValues["Planned_Completion_Date"] = (tc.Tabs[8].FindControl("txtPlannedCompletionDate") as TextBox).Text;
    e.NewValues["Signed_Off_By__BGL_"] = (tc.Tabs[8].FindControl("txtSignedOffByBGL") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtSignOffDateBGL") as TextBox).Text))
        e.NewValues["Sign_Off_Date__BGL_"] = null;
    else
        e.NewValues["Sign_Off_Date__BGL_"] = (tc.Tabs[8].FindControl("txtSignOffDateBGL") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtActualReviewDate") as TextBox).Text))
        e.NewValues["Actual_Review_Date"] = null;
    else
        e.NewValues["Actual_Review_Date"] = (tc.Tabs[8].FindControl("txtActualReviewDate") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtActualCompletionDate") as TextBox).Text))
        e.NewValues["Actual_Completion_Date"] = null;
    else
        e.NewValues["Actual_Completion_Date"] = (tc.Tabs[8].FindControl("txtActualCompletionDate") as TextBox).Text;
    e.NewValues["Signed_Off_By__Mill_Manager_"] = (tc.Tabs[8].FindControl("txtSignedOffByMillManager") as TextBox).Text;
    if (String.IsNullOrEmpty((tc.Tabs[8].FindControl("txtSignOffDateMillManager") as TextBox).Text))
        e.NewValues["Sign_Off_Date__Mill_Manager_"] = null;
    else
        e.NewValues["Sign_Off_Date__Mill_Manager_"] = (tc.Tabs[8].FindControl("txtSignOffDateMillManager") as TextBox).Text;
}

编辑 2

我已经尝试在我拥有与 LinqDataSource 和 FormView 相关的处理程序的唯一事件中设置断点,并且在异常发生之前没有任何事件被触发。这些事件是:

  • LinqDataSource_Selecting
  • FormView_ItemUpdating
  • FormView_DataBound

单击“保存”按钮后,我的所有断点均未到达。它在这里爆炸,不是很有用:

这是我的 FormView 声明:

<asp:FormView ID="fvIncident" runat="server" DefaultMode="Edit" 
    DataSourceID="ldsIncidents" DataKeyNames="Incident_Number" 
    AllowPaging="True" CssClass="full" ondatabound="fvIncident_DataBound" 
    onitemupdating="fvIncident_ItemUpdating">

还有我的 LinqDataSource 声明:

<asp:LinqDataSource ID="ldsIncidents" runat="server" 
    ContextTypeName="PRIDE.PRIDEDataContext" EnableUpdate="True" EntityTypeName="" 
    TableName="Incidents" OrderBy="Incident_Number DESC" 
    onselecting="ldsIncidents_Selecting">
</asp:LinqDataSource>

【问题讨论】:

  • 试用:if (!String.IsNullOrEmpty(Request.QueryString["id"])) { int id = Convert.ToInt32(Request.QueryString["id"]); e.Result = db.Incidents.Where(i =&gt; i.Incident_Number == id ); }
  • 这就是我在Selecting事件中已经拥有的代码,除了多了一个不必要的步骤......
  • 请发布 FormView 和 ItemTemplate 声明和设置代码以及调用 FormView.UpdateItem(true) 的方式/位置。您的错误在其他地方,不在您发布的代码中。意思是,它不是由您发布的代码引起的,即使此时它可能会被抛出。
  • @DavidKhaykin formview 代码有 900 行长(是的,这很糟糕)。如果我注释掉 Selecting 事件,一切似乎都可以正常工作。奇怪的是Selecting 事件在抛出异常时甚至不会被触发。由于我不希望任何人通过 900 行 FormView 代码,我想一个更合适的问题是如何追踪这个问题?我在一个按钮中调用FormView.UpdateItem(true),除了try/catch之外没有其他代码。
  • 页面加载时确实会触发该事件,但当我使用 UpdateItem 从按钮保存时不会触发。

标签: c# .net formview linqdatasource


【解决方案1】:

试试这个。

IQueryable<Incident> query = this.context.Incidents;
string whereCaluse = String.Format("Incident_Value=={0}",Request.QueryString["id"]);
query.Where(whereClause);
e.Result=query;

【讨论】:

  • Where 方法需要一个谓词。如果您的意思是在 LinqDataSource 上设置 Where,我也尝试过,它会导致同样的问题。它可以很好地过滤数据,但是一旦我尝试保存 FormView,就会出现上述异常。
  • 对不起,我误解了你。如果您还没有,我建议您也处理 OnUpdating 事件。 Check this out
  • 那场比赛我该怎么办?
【解决方案2】:

通过查看异常细节,我可以说i.Incident_Number 可能是对象类型。

所以,您也可以尝试在 linq 表达式中将 i.Incident_Number 转换为 int。喜欢:

protected void ldsIncidents_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    if (!String.IsNullOrEmpty(Request.QueryString["id"]))
    {
        e.Result = db.Incidents.Where(i => Convert.ToInt32(i.Incident_Number) == Convert.ToInt32(Request.QueryString["id"]));
    }
}

【讨论】:

  • Inciden_Number 是Int32?,我猜Request.QueryString['id'] 是对象,由于某种原因,它在运行时没有获取参数的值。
  • 如果我过于简单化,或者咖啡还没有开始,请原谅我......但我认为您无法比较 Int32?在 Int32 上不做 .Value 的 int 吗?
【解决方案3】:

也许你应该使用 TryParse

protected void ldsIncidents_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
    if (!String.IsNullOrEmpty(Request.QueryString["id"]))
    {
        int id;
        e.Result = db.Incidents.Where(i => i.Incident_Number == Int32.TryParse(Request.QueryString["id"], out id) ? id : 0);
    }
}

编辑

要验证我在下面的建议,您可以这样做来检查您的价值观

    protected void ldsIncidents_Selecting(object sender, LinqDataSourceSelectEventArgs e)
    {
        if (!String.IsNullOrEmpty(Request.QueryString["id"]))
        {
            int id;

            // now you can check the values you gat;
            var queryString = Request.QueryString["id"];
            int iNr =Int32.TryParse(queryString, out id) ? id : 0;

            e.Result = db.Incidents.Where(i => i.Incident_Number == iNr);
        }
    }

【讨论】:

  • 我必须在星期一回去工作时试试这个,谢谢你的帖子。
  • @Hoff 让我知道你的结果如何:)。周末愉快。
  • @Hoff 哪里可以解决您的问题?
  • 不,不幸的是同样的问题。
  • @Hoff 哇,这很有趣,所以您的 i.Incident_Number 之一将是一个对象,因为 Int32.TryParse(Request.QueryString["id"], out id) ? id : 0 的结果现在应该始终是 Int
【解决方案4】:

好吧,不管你信不信,这已通过实施来自this SO question 的修复程序来解决。微软迫切需要解决这个问题。我将寻呼机设置更改为仅显示在 FormView 的底部并停止抱怨。

【讨论】:

  • 很高兴你解决了。我在这个问题上挠了很久!
猜你喜欢
  • 1970-01-01
  • 2021-09-24
  • 2016-07-16
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
  • 2021-02-19
相关资源
最近更新 更多