【问题标题】:using one line if in linq statement如果在 linq 语句中使用一行
【发布时间】:2014-04-27 09:55:06
【问题描述】:

我有多个默认值为 0 的下拉列表,表示用户未选择任何选项,其他数字平均用户选择了一个值,它应该包含在 LINQ 查询中。我的问题是我无法检查用户是否在下拉列表中选择了任何选项?

这是我尝试的第一个下拉列表:

var ddl1 = Convert.ToInt32(ddlDastgAhasli.SelectedValue);


var project = (from p in context.Projects 
               where Convert.ToInt32(p.DastgahEjraeiAsli) == ((ddl1 == 0) ? null : ddl1) select p);

这是错误:

无法确定条件表达式的类型,因为没有隐式对话''和'int'

【问题讨论】:

  • 它是asp.net im使用
  • 看起来有一个Project,其中p.DastgahEjraeiAsli 是一个空字符串,无法转换为整数,但是我不太清楚您的确切示例将如何编译。

标签: c# asp.net linq


【解决方案1】:

这里有两个问题:

  1. 您不能将值类型(在您的情况下为 int)与 null 进行比较。
  2. 您需要选择一些东西。

这是查询的结构:

var project = (from p in context.Projects where p.prop == 1 select p);

然后解析 int:

不好

string strInt = "7";    
if(Convert.ToInt32(strInt) == null) //  compilation error 

string strInt = "7";   
int intVal;
if(int.TryParse(strInt, out intVal))
{
   // intVal is an integer
}
else
{
  // intVal isnt an integer
}

【讨论】:

  • 我的目标是 if (ddl1 == 0) 跳过 where。
  • 你可以简单地 if\else 这个。你的问题在哪里?
  • 通过在 linq 查询中将 int 数替换为 null 错误消失但我不想将 "Convert.ToInt32(p.DastgahEjraeiAsli)" 与我想要的数字进行比较 if (ddl1 == 0) 跳过这就是我使用 null 的原因。你能提供一个例子来说明如何做到这一点吗?
  • 用 if\else 来做。这将需要 2 多行代码,但您的代码将易于阅读\调试\理解。放置“null”和“禁用 where”并不是真正正确的做法。如果您坚持这样做,请使用可为 null 的 int(可以是 null 或 int)。
【解决方案2】:

如果您只想在未设置 ddl1 时跳过 where 条件,则可以在实际需要时有条件地添加 where 子句,例如(与所有 ddls 比较的有点愚蠢的示例相同的字段)

var project = (from p in context.Projects select p);

if(ddl1 != 0)
{
    project = project.Where(Convert.ToInt32(p.DastgahEjraeiAsli) == ddl1);
}

if(ddl2 != 0)
{
    project = project.Where(Convert.ToInt32(p.DastgahEjraeiAsli) == ddl2);
}

...

这将有效地要求所有 ddlx != 0 为 true 的 where 子句,并且 ddl 为 0 的子句不会以任何方式影响查询。

【讨论】:

  • 是的,但是如果只有一个 ddl,这将起作用,但在这种情况下,其中有很多,用户可以选择其中一个或多个。例如 ddl2,ddl3, ... 和
  • @farhang67 没有什么能阻止你动态添加多个条件,我会更新答案。
  • 它应该在一个对象中返回查询结果,但是使用这个 sn-p 并不能满足这个要求
  • @farhang67 我不确定您所说的“一个对象”是什么意思,您的原始问题和此查询都构建了一个您可以评估的IQueryable<Project>,例如使用ToArray() 来获取匹配结果。
  • 这里的问题是用户可以选择 ddl1 和 ddl3 但不是 ddl2 在这种情况下 linq 查询应该是这样的: from p in mycontext.mytable where ddl1 == p.myrecord && ddl3 == p.myrecord2。我们不知道用户会选择什么,有很多可能性,并且需要很多 if 语句。
【解决方案3】:

这是一个非常有用的扩展方法,我在我的项目中使用它来解决各种检查..它不仅仅是 ASP.NET..你也可以在 winforms 等中使用它。

    public IEnumerable<Control> GetAll(Control control)
     {        
       var controls = control.Controls.Cast<Control>();

       return controls.SelectMany(ctrl => GetAll(ctrl))
       .Concat(controls)
       .Where(c => c.Visible == true);
//If you don't need to check that the control's visibility then simply ignore the where clause..

     }

使用此方法,无论您的控件(在您的情况下拉列表中)是该控件下的另一个控件的成员/子控件,您将控件作为参数传递给该方法..方法从给定参数开始递归检查并检查所有子控件与给定控件相关的控件作为方法参数..

代码中的用法:

    //Its Assumed you need to check DropDownList' SelectedIndex property

      List<Control> dropDownsOfPageWhichTheirSelectedIndexIsZero
                            = new List<Control>( GetAll ( YourAspNetPage )
                              .Where( x => x is DropDownList 
                              && ( ( DropDownList ) x ) . SelectedIndex == 0 ) ) ;

// Lets check if our page has dropdowns which their SelectedIndex equals to Zero
if ( dropDownsOfPageWhichTheirSelectedIndexIsZero . Count > 0 )
{
  // do your work what you need in your project
  //suppose you need their names and do something with this name (i.e.warn a message to user)

    foreach ( DropDownList ddl in dropDownsOfPageWhichTheirSelectedIndexIsZero )
    {
      alert ("Please Check "+ ddl.Name +".Should Chost other than \"Select\" option");
    }
} 

希望这有帮助..

【讨论】:

    【解决方案4】:

    通过放置“Convert.ToInt32(p.DastgahEjraeiAsli)”而不是 null 来解决问题,因此如果 ddl1 == 0(用户没有选择任何项目)会跳过。

    var project = (from p in context.Projects 
               where Convert.ToInt32(p.DastgahEjraeiAsli) == ((ddl1 == 0) ? Convert.ToInt32(p.DastgahEjraeiAsli) : ddl1) select p);
    

    当您有一个包含多个 texbox 和下拉列表的搜索表单并且用户可以选择它们中的每一个并且您不知道哪个会被选择而哪个不会被选择时,这非常有用。

    简化示例:

    在搜索按钮点击事件中:

    int ddl1 = Convert.ToInt32(dropdownlist1.selectedvalue);
    int ddl2 = Convert.ToInt32(dropdownlist2.selectedvalue);
    string txt1 = textbox1.text;
    
    
    var project = (from p in context.mytable
                           where p.field1 == ((ddl1 == 0) ? p.field1 : ddl1)
                                       && p.field2 == ((ddl2 == 0) ? p.field2 : ddl2)
                                       && p.field3 == ((txt1 == "") ? p.field3 : txt1)
    
                           select p).ToList();
    
    
    gridview1.datasource = project;
    fridview1.databind();
    

    不是:每个下拉列表都有一个默认值,text="select an item" 和 value="0",所以如果用户没有选择任何选项,默认值仍然是 0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      相关资源
      最近更新 更多