Mangrio
Mangrio

Reputation: 1020

Comparison with multiple Where clause in LINQ C#

I have two DataTables:

DataTable dtCatalogFromMySql;
DataTable dtDataForExistingProducts;

dtCatalogFromMySql

Id | productname  | barcode  | pricesell| type  
---+--------------+----------+----------+------
1  | Abz          | 123      | 2.01     | RS // different product name
2  | Abd          | 122      | 8.90     | RS // different price
3  | Abx          | 125      | 21.00    | WS  // both different
4  | Abf          | 124      | 2.11     | RS
5  | Abg          | 126      | 8.01     | WS 
6  | Abh          | 127      | 60.23    | RS
7  | Abi          | 128      | 9.10     | RS

dtDataForExistingProducts

Id | productname  | barcode  | pricesell| type  
---+--------------+----------+----------+------
1  | Abc          | 123      | 2.01     | RS
2  | Abd          | 122      | 3.90     | RS
3  | Abe          | 125      | 23.00    | WS 
4  | Abf          | 124      | 2.11     | RS
5  | Abg          | 126      | 8.01     | WS 
6  | Abh          | 127      | 60.23    | RS
7  | Abi          | 128      | 9.10     | RS

I need return only rows which are different as in first table

I need select all data where Prod_No equals to baracode and Descript not equals to productname and Retail_PRC also not equals to pricesell.

I am not getting results with this code

List<DataRow> matchingRows = dtCatalogFromMySql.AsEnumerable()
    .Where(a => dtDataForExistingProducts.AsEnumerable()
        .Select(b => b.Field<string>("Prod_No"))  
        .Contains(a.Field<string>("barcode")))
    .Where(a => !dtDataForExistingProducts.AsEnumerable()
        .Select(b => b.Field<string>("Descript"))
        .Equals(a.Field<string>("productname")))
    .Where(a => !dtDataForExistingProducts.AsEnumerable()
        .Select(b => b.Field<decimal>("Retail_PRC"))
        .Equals(Convert.ToDecimal(a.Field<double>("pricesell"))))
    .ToList();

I suppose, Contains() will also fetch the data if barcode = 123456 and Prod_No = 1234, it is right? If I am right what is right way to compare string exactly same

Upvotes: 0

Views: 412

Answers (2)

Jim Berg
Jim Berg

Reputation: 659

You may want to consider a clearer syntax such as:

var results = from t1 in dtCatalogFromMySql.AsEnumerable()
              join t2 in dtDataForExistingProducts.AsEnumerable() on 
                  (string)t1["barcode"] equals (string)t2["Prod_No"]
              where (string)t1["productname"] != (string)t2["descript"] &&
                    Convert.ToDecimal((double)t1["pricesell"]) != 
                    (decimal)t2["Retail_PRC"]
              select t2;

The Join is definitely the way to go. You can modify the select according to your required result set.

trighati makes a good point about using OR instead of AND. This is assuming that you want all of the data where at least one of your values changed where Prod_no and barcode are equal. This would change the query to be:

var results = from t1 in dtCatalogFromMySql.AsEnumerable()
              join t2 in dtDataForExistingProducts.AsEnumerable() on
                  (string)t1["barcode"] equals (string)t2["Prod_No"]
              where (string)t1["productname"] != (string)t2["descript"] ||
                    Convert.ToDecimal((double)t1["pricesell"]) != 
                    (decimal)t2["Retail_PRC"]
              select t2;

Upvotes: 1

Bozhidar Stoyneff
Bozhidar Stoyneff

Reputation: 3634

Use Join to combine them into one result set, then filter the result set:

var combined = dtDataForExistingProducts.AsEnumerable()
    .Join(dtCatalogFromMySql.AsEnumerable(), 
        ep => ep.Field<string>("Prod_No")
        ce => ce.Field<string>("barcode"), 
        (ep, ce) => new {ExistingProduct = ep, CatalogEntry = ce})
    .Where(m => !m.ExistingProduct.Field("Descript")
        .Equals(m.CatalogEntry.Field("productname")))
    .Where(m => decimal.Parse(m.ExistingProduct.Field("Retail_PRC").ToString()) 
        != decimal.Parse(m.CatalogEntry.Field("pricesell").ToString()))
    .ToList()
;

Upvotes: 0

Related Questions