Reputation: 139
Can anyone help with this, I'm trying to perform a simple query using LINQ and I am not getting the expected results.
private void ButtonProductSearch_Click(object sender, EventArgs e)
{
string userSearch = textBoxSearchText.Text.ToLower();
var productSearch =
from product in sales
where product.ToString().ToLower() == userSearch
select product;
MessageBox.Show(productSearch.Count().ToString()); //For Testing
sales.Clear();
sales.AddRange(productSearch);
DisplaySales(sales);
}
The message, which is just for testing is returning 0, I have ensured that I am entering a relevant search string.
sales is a Sale object, which is populated from a csv file, and there is a dataGridView which is populated from the Sale object, screenshot below. When th application is run, sales reads every line from the csv, and datagridview populates with that data, screenshot below
Upvotes: 0
Views: 185
Reputation: 45109
I think the answer from @dotNET seems for me to be the correct answer. Just for completeness I build up an example and also implemented case insensitive search:
using System;
using System.Linq;
using Bogus;
public class Program
{
public static void Main()
{
var productsFactory = new Faker<Product>()
.StrictMode(true)
.RuleFor(p => p.TransactionDate, f => f.Date.Between(DateTime.UtcNow.AddDays(-100), DateTime.UtcNow))
.RuleFor(p => p.Category, f => f.Commerce.ProductAdjective())
.RuleFor(p => p.Price, f => f.Random.Decimal(10, 100))
.RuleFor(p => p.PaymentType, f => f.PickRandomWithout(PaymentType.Unknown))
.RuleFor(p => p.Name, f => f.Commerce.ProductName())
.RuleFor(p => p.City, f => f.Address.City())
.RuleFor(p => p.State, f => f.Address.State())
.RuleFor(p => p.Country, f => f.Address.Country());
var products = productsFactory.Generate(50);
var userSearch = products.Skip(3).First().Name.Substring(2, 3);
var productSearch = products.Where(product => product.Name.IndexOf(userSearch, StringComparison.CurrentCultureIgnoreCase) >= 0);
foreach (var result in productSearch)
{
Console.WriteLine(String.Format("{0:G} {1} {2:N2}", result.TransactionDate, result.Name, result.Price));
}
Console.ReadKey();
}
}
public class Product
{
public DateTime TransactionDate { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
public PaymentType PaymentType { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
}
public enum PaymentType
{
Unknown,
Mastercard,
Visa,
Amex,
}
Upvotes: 0
Reputation: 35470
You need to understand that in the query from product in sales
, product
refers to a row of sales
and not to the column named Product
. Therefore doing ToString()
on product
will return that row's string representation (which is most often the name of the class itself). You should write your query like this:
var productSearch =
from s in sales
where s.Product.ToLower() == userSearch
select product;
Here again, s
refers to a row of sales and therefore has got all the properties like Product, Price and Payment Type etc. You can therefore ask LINQ to filter for rows that have their Product
property equal to userSearch
. Since Product
is of type string, you don't even need to do ToString()
on it.
Upvotes: 2