【问题标题】:How to avoid null values in LINQ command?如何避免 LINQ 命令中的空值?
【发布时间】:2014-05-20 14:18:49
【问题描述】:

我正在尝试使用实体框架从其列表中搜索对象。

我有以下对象结构

public class Product
{
    public int Id { get; set; }
    public string ProductName { get; set; }
    public double Size { get; set; }
}

然后我创建产品列表

private List<Product> AddProducts()
{
    List<Product> ProductList = new List<Product>();

    oProduct Product = new Product();
    oProduct.Id = 1;
    oInventory.ProductName = "Product1";
    oProduct.Size = 25;
    ProductList.Add(oProduct);

    oProduct Product = new Product();
    oProduct.Id = 2;
    oInventory.ProductName = "Product2";
    oProduct.Size = 25;
    ProductList.Add(oProduct);

    return ProductList;           
}

现在,我正在尝试从上述列表形式的 ProductName 参数中搜索对象。

我使用了下面的代码。

public ActionResult Index(string productname = "", string size = "")
{
    var oProdList = from ProdList in AddProducts() select oProdList;
    oProdList = oProdList.Where(oProd => oProd.ProductName.ToUpper().Contains(ProductName.ToUpper().Trim())|| oProd.Size.ToString().ToUpper().Contains(size.ToUpper().Trim()));
    ViewBag.ProductList = oProdList;
    return View();
}

现在请检查下面的图片,我有产品列表,我正在尝试通过在文本框中输入 Product1 来查找它,并将尺寸文本框保留为空白。 现在,当我单击 submit 时,我将这两个变量传递给 Index 方法(上一个)进行搜索,但 LINQ 命令返回两条记录 Product1 和 Product 2 但它应该只返回一条记录

如何处理?

【问题讨论】:

    标签: c# linq entity-framework-4 linq-to-entities


    【解决方案1】:

    这对我有用,也是搜索算法应该如何工作的。你想&amp;&amp; 参数,如果它们都提供,但|| 它们如果缺少其中一个参数。

    还需要注意的是,输入“2”将匹配 size 的“25”,因为我们正在执行 Contains。如果您希望它仅在您输入“25”而不是“2”时匹配,请将其设置为 == 而不是 Containsproductname 也是如此。

    public class Product
    {
      public int Id { get; set; }
      public string ProductName { get; set; }
      public double Size { get; set; }
    }
    
    private List<Product> AddProducts()
    {
      List<Product> ProductList = new List<Product>();
    
      var p = new Product();
      p.Id = 1;
      p.ProductName = "Product1";
      p.Size = 25;
      ProductList.Add(p);
    
    
      var p2 = new Product();
      p2.Id = 2;
      p2.ProductName = "Product2";
      p2.Size = 25;
      ProductList.Add(p2);
    
      return ProductList;           
    }
    
    public ActionResult Index(string productname = "", string size = "")
    {
      var oProdList = from p in AddProducts() select p;
    
      if (!string.IsNullOrWhiteSpace(productname) && !string.IsNullOrWhiteSpace(size))
      {
         oProdList = oProdList.Where(p => p.ProductName.ToUpper().Trim().Contains(productname.ToUpper().Trim()) && p.Size.ToString().Contains(size.Trim()));
      }
      else
      {
        oProdList = oProdList.Where(p => !string.IsNullOrWhiteSpace(productname) ? p.ProductName.ToUpper().Trim().Contains(productname.ToUpper().Trim()) : p.ProductName.ToUpper().Trim() == productname.ToUpper().Trim() || !string.IsNullOrWhiteSpace(size) ? p.Size.ToString().Contains(size.Trim()) : p.Size.ToString() == size.Trim());
      }
    
      ViewBag.ProductList = oProdList;
      return View();
    }
    

    【讨论】:

      【解决方案2】:

      发生这种情况是因为每个字符串值都包含字符串空 并且您的参数大小默认值设置为 string.empty 所以你应该检查它是否像这样过滤结果

          oProdList = oProdList.Where(
              oProd =>(productname == string.Empty ? false:
                      oProd.ProductName.ToUpper().Contains(productname.ToUpper().Trim()))
                      || (size == string.Empty ? false:oProd.Size.ToString().
                      ToUpper().Contains(size.ToUpper().Trim()))
              );
      

      【讨论】:

      • 它只对产品名称起作用,如果我同时提到产品名称和尺寸,它仍然只根据产品名称返回......它不考虑尺寸。
      【解决方案3】:

      我认为原因可能是因为您将大小转换为字符串

      试试这个

      public ActionResult Index(string productname = "", string size = "0")
              {
                  var oProdList = from ProdList in AddProducts() select oProdList;
      
      
            oProdList = oProdList.Where(oProd => oProd.SectionName.ToUpper().Contains(ProductName.ToUpper().Trim())|| oProd.Size == (double)size));
      
      
                  ViewBag.ProductList = oProdList;
                  return View();
      
              }
      

      【讨论】:

      • 我认为问题在于空白值....如果我将大小参数设置为空白,那么它会返回两个记录...
      • 您应该比较相同的类型,我建议您将 Size 设置为可为空(双精度?),以便您可以检查空白尺寸
      【解决方案4】:

      您可以在此处使用 null 合并运算符。

          oProdList = oProdList.Where(oProd => (!String.IsNullOrEmpty((ProductName??"").Trim()) &&
          oProd.ProductName.ToUpper().Contains(ProductName.ToUpper().Trim()) 
      || (!String.IsNullOrEmpty((size??"").Trim()) && oProd.Size.ToString().ToUpper().Contains(size.ToUpper().Trim())));
      

      【讨论】:

      • 我正在使用它进行搜索,用户只能输入 productName 或者可能同时输入 ProductName 和 Size....
      【解决方案5】:

      如果搜索参数为空,您需要指定忽略搜索。

      试试这个:

      var productList = from ProdList in AddProducts()
      where (productname.Trim() == string.Empty || ProdList.ProductName.ToUpper().Contains(ProductName.ToUpper().Trim()))
      && (size.Trim() == string.Empty || ProdList.Size.ToString().ToUpper().Contains(size.ToUpper().Trim()))
      select ProdList;
      

      【讨论】:

      • 试试修改后的版本。我将 Trim() 添加到参数中。发布时这些值可能不为空。
      • 问题在于空白值...它在命令中返回 true,因此它的返回调用值...
      • 仅在我仅输入 Productname 时有效,当我将值放入两个文本框中时无效...用户可以同时输入两个字段或任何字段...我们不能假设用户每次都可以输入 productName。 ..
      【解决方案6】:
      if(!String.IsNullOrWhiteSpace(oProd.SectionName)){
          oProdList = oProdList.Where(oProd => oProd.SectionName.ToUpper().Contains(ProductName.ToUpper().Trim());
      }
      
      if(!String.IsNullOrWhiteSpace(oProd.Size)){
          oProdList = oProdList.Where(oProd => oProd.Size.ToUpper().Contains(size.ToUpper().Trim());
      }
      

      【讨论】:

      • 如果两个命令返回不同的结果集,它将覆盖oProdList?
      • 我不想覆盖它...我想用多个参数进行搜索,如果任何参数为空则返回所有记录...
      • 这两天我一直在想,为什么这么难?
      • 为什么要投反对票!!!这里我正在做的是构建查询,它不会获取数据,直到你调用类似ToList() 等的调用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 2021-04-25
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多