bnil
bnil

Reputation: 1541

How to avoid null values in LINQ command?

I am trying to search the object from its list using entity framework.

I have following structure of the object

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

and I create the list of the product

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

Now, I am trying to search the object form the above list form ProductName parameter.

I have used below code.

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

Now Please check picture below, I have list of products and I am trying to find the Product1 by typing it in text box and I keep the size textbox blank. now when I click on submit , I pass these two varibles for searching in Index method (above one) but the LINQ command returns the both records, Product1 and Product 2 but it should return only one record

How to deal with this ?

enter image description here

Upvotes: 1

Views: 2917

Answers (6)

Jason Roell
Jason Roell

Reputation: 6819

This worked for me and is how a search algorithm should work. You want to && the parameters if they are both provided but || them if one of the arguments is missing.

Also its good to note that an input of "2" will match "25" for the size because we are preforming a Contains. If you want it only to match when you enter "25" and not "2" set it to == instead of Contains. Same goes for productname.

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

Upvotes: 2

Hossein Salmanian
Hossein Salmanian

Reputation: 763

that happen because every string value contain string empty and your parameter size default value set to string.empty so you should check it for filtering the result like this

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

Upvotes: 1

Ganesh
Ganesh

Reputation: 245

You need to specify to ignore search if the search params are empty.

Try this:

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;

Upvotes: 0

Victor Mukherjee
Victor Mukherjee

Reputation: 11065

You can use the null coalescing operator here.

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

Upvotes: 0

Damith
Damith

Reputation: 63105

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

Upvotes: -1

Tinu
Tinu

Reputation: 197

I think the cause might be because of you are converting size to string

Try this

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

        }

Upvotes: 0

Related Questions