vb.net update datatable column from join and sum with LINQ - c#

I have two datatables which are
dtOrder
orderid | trackno | totalamount
----------+--------+------------
1 | test1 | 0
2 | test2 | 0
3 | test3 | 0
4 | test4 | 0
5 | test5 | 0
6 | test6 | 0
7 | test7 | 0
8 | test8 | 0
dtAmounts
id | amount | trackno |
---+----------+--------+
1 | 5 | test1 |
2 | 10 | test2 |
3 | 15 | test1 |
4 | 10 | test4 |
5 | 20 | test1 |
6 | 30 | test6 |
7 | 15 | test4 |
8 | 10 | test6 |
I need to join and get the sum of amounts based on track numbers so resulting datatable should be:
orderid | trackno | totalamount
----------+--------+------------
1 | test1 | 40
2 | test2 | 10
3 | test3 | 0
4 | test4 | 25
5 | test5 | 0
6 | test6 | 40
7 | test7 | 0
8 | test8 | 0
How can i achieve this using LINQ with VB.net?

C# :
var req = (from Ord in dtOrder
join Am in dtAmounts
on Ord.trackno
equals Am.trackno into tbResult
select new
{
orderid = Ord.orderid ,
trackno = Ord.trackno ,
totalamount = cl.PrenomClient ,
amount = Am.GetChildRows("amount").Sum()
}).ToList();
VB:
Dim req = (From Ord In dtOrderJoin Am In dtAmounts On Ord.trackno = Am.trackno Into tbResultNew With { _
Key .orderid = Ord.orderid, _
Key .trackno = Ord.trackno, _
Key .totalamount = cl.PrenomClient, _
Key .amount = Am.GetChildRows("amount").Sum() }).ToList()

Related

Color the datagridview there where it found a difference with SQL

I got some code which makes an SQL query and pastes the result into a datagridview. This works perfectly. The code be seen below:
private void FillInDataGrid()
{
string cn = ConfigurationManager.ConnectionStrings["Scratchpad"].ConnectionString;
SqlConnection myConnection = new SqlConnection(cn);
string sql =
"SELECT " +
" dbo.new.[column1], dbo.new.[column2], dbo.new.[column3], dbo.new.[column4] from dbo.new" +
"except " +
"select dbo.old.[column1], dbo.old.[column2], dbo.old.[column3], dbo.old.[column4] from dbo.old"
;
SqlDataAdapter dataadapter = new SqlDataAdapter(sql, myConnection);
DataSet ds = new DataSet();
myConnection.Open();
dataadapter.Fill(ds, "Authors_table");
myConnection.Close();
dataGridView1.DataSource = ds;
dataGridView1.DataMember = "Authors_table";
}
This code displays the values of the row from the new table if it doenst exists in the old table. Now I want to color the cells where they differ. So for example if you have those two tables:
new table:
--------------------------------------
| column1 | column2| column3| column4|
--------------------------------------
| 1 | 1 | 1 | 2 |
--------------------------------------
| 2 | 2 | 3 | 2 |
--------------------------------------
| 6 | 7 | 9 | 8 |
--------------------------------------
| 7 | 5 | 34 | 22 |
--------------------------------------
| 3 | 4 | 3 | 3 |
--------------------------------------
old table:
--------------------------------------
| column1 | column2| column3| column4|
--------------------------------------
| 6 | 7 | 9 | 8 |
--------------------------------------
| 7 | 5 | 34 | 22 |
--------------------------------------
| 1 | 1 | 1 | 1 |
--------------------------------------
| 2 | 2 | 2 | 2 |
--------------------------------------
| 3 | 3 | 3 | 3 |
--------------------------------------
So this example would show:
--------------------------------------
| column1 | column2| column3| column4|
--------------------------------------
| 1 | 1 | 1 | *2* |
--------------------------------------
| 2 | 2 | *3* | *2* |
--------------------------------------
| 3 | *4* | *3* | *3* |
--------------------------------------
Where the * 2 *, * 3 * and * 4 * would show a color in the datagridview.
Thanks in advance for your help.

C# Datatable - group by multiple columns with linq

I have a Datatable like this
| Supplier | Product | Price1 | Price2 | Price3 | ... | PriceN |
|-----------|---------|--------|--------|--------|-----|--------|
| Supplier1 | Orange | 100 | 105 | 150 | ... | 180 |
| Supplier1 | Orange | 110 | 130 | 140 | ... | 180 |
| Supplier2 | Orange | 200 | 250 | 270 | ... | 350 |
| Supplier2 | Orange | 250 | 270 | 320 | ... | 270 |
I want to group rows as next:
| Supplier | Product | Price1 | Price2 | Price3 | ... | PriceN |
|-----------|---------|---------|---------|---------|-----|---------|
| Supplier1 | Orange | 100-110 | 105-130 | 140-150 | ... | 180 |
| Supplier2 | Orange | 200-250 | 250-270 | 270-320 | ... | 270-350 |
Count of columns like "PriceN" can be arbitrary.
How can I do this with LINQ?
You can group by Supplier and Product as
var result = from x in data
group x by new { x.Supplier, x.Product }
select x;
or
var result = data.GroupBy(x => new { x.Supplier, x.Product });
similarly you can use any number of property in group clause
you have to group by it separately in another lambda expression
result.tolist().GroupBy(p=> p.x,p.x2,p.x3 ...);
You can use GroupBy and JOIN to concatenate the values of the price columns:
var groupedSupplier = supplier.GroupBy(s => new { s.Supplier, s.Product })
.Select(supplier => supplier.Supplier,
supplier.Product,
supplier.Price1 = string.Join(",", supplier.Select(x => x.Price1)),
supplier.Price2 = string.Join(",", supplier.Select(x => x.Price2)),
...);
To group by multiple columns in lambda expression use:
var groupedSupplier = supplier.GroupBy(s => s.Supplier,
s => s.Product)
For details, please see chapter 11 of "C# in Depth" by Jon Skeet, Chapter 11 "Query expressions and LINQ to Objects: 11.6 Groupings and continuations", http://csharpindepth.com/

Join 2 datatable on difference columns

I have 2 DataTable. I want to use LINQ to join the 2 datatable on difference columns. How to do that?
Table A:
+--------+-------+-------+
| ACol1 | ACol2 | ACol3 |
+--------+-------+-------+
| 1 | tbA12 | tbA13 |
| 2 | tbA22 | tbA23 |
| 3 | tbA32 | tbA33 |
| 4 | tbA42 | tbA43 |
| 5 | tbA52 | tbA53 |
+--------+-------+-------+
Table B:
+-------+-------+-------+
| BCol1 | BCol2 | BCol3 |
+-------+-------+-------+
| 1 | XX | tbB13 |
| XX | 1 | tbB23 |
| XX | 2 | tbB33 |
| 4 | XX | tbB43 |
+-------+-------+-------+
SQL Query:
SELECT a.*, b.BCol3
FROM tableA a
JOIN tableB b ON a.ACol1=b.BCol1 OR a.ACol1=b.BCol2
Expected Result:
+--------+-------+-------+-------+
| ACol1 | ACol2 | ACol3 | BCol3 |
+--------+-------+-------+-------+
| 1 | tbA12 | tbA13 | tbB13 |
| 1 | tbA12 | tbA13 | tbB23 |
| 2 | tbA22 | tbA23 | tbB33 |
| 4 | tbA42 | tbA43 | tbB43 |
+--------+-------+-------+-------+
Currently my LINQ query are below:
var query1= from rowA in tableA.AsEnumerable()
join rowB in tableB.AsEnumerable()
on rowA["ACol1"].ToString() equals rowB["BCol1"].ToString()
select new
{
rowA["ACol1"],
rowA["ACol2"],
rowA["ACol3"],
rowB["BCol3"]
};
var query2= from rowA in tableA.AsEnumerable()
join rowB in tableB.AsEnumerable()
on rowA["ACol1"].ToString() equals rowB["BCol2"].ToString()
{
rowA["ACol1"],
rowA["ACol2"],
rowA["ACol3"],
rowB["BCol3"]
};
var result=query1.Union(query2);
Any better idea how to solve this?
LINQ support for JOIN with non-trivial conditions is very limited. You could do a cross join + move your condition to where clause.
var query1= from rowA in tableA.AsEnumerable()
from rowB in tableB.AsEnumerable()
where rowA["ACol1"].ToString() == rowB["BCol1"].ToString()
|| rowA["ACol1"].ToString() == rowB["BCol2"].ToString()
select new
{
rowA["ACol1"],
rowA["ACol2"],
rowA["ACol3"],
rowB["BCol3"]
};
Try this:-
var result = from a in tableA.AsEnumerable()
from b in tableB.AsEnumerable()
where a.Field<string>("ACol1") == b.Field<string>("BCol1")
|| a.Field<string>("ACol1") == b.Field<string>("BCol2")
select new
{
a["ACol1"],
a["ACol2"],
a["ACol3"],
b["BCol3"]
};
Here is the complete working Fiddle, you can copy paste the same in your editor and test because its not supporting AsEnumerable in DotNetFiddle.

Group and count in linq C#

I have a query that needs to retrieve 3 fields:
| MaintenanceID | MaintenanceIDCount | StatusID |
| 1 | 2 | -1 |
| 3 | 2 | -1 |
The field MaintenanceIDCount (like the name says), is the count of MaintenanceID column.
My basic query expression is above:
var result = from m in Maintenance
select new
{
m.MaintenanceID,
m.StatusID
}
The result of this query is:
| MaintenanceID | StatusID |
| 1 | -1 |
| 1 | -1 |
| 3 | -1 |
| 3 | -1 |
How can I group and mount my query to retrieve a column with the MaintenanceID column count?
Some tips?
from m in Maintenance
group m by new { m.MaintenanceID, m.StatusID } into g
select new {
g.Key.MaintenanceID,
g.Key.StatusID,
MaintenanceIDCount = g.Count()
}

How to take the difference of two sums in two tables in mysql

I have two tables to treat in a query for getting the product in hand.
ProdBiscuit
+----+-----+-------+---------------+
| ID | QTY |StockID| Name |
+----+-----+-------+---------------+
| 1 | 100 | 1 | Bis Chocolat |
+----+-----+-------+---------------+
| 2 | 120 | 2 | Bis Moutarde |
+----+-----+-------+---------------+
| 3 | 100 | 3 | Bis Epice |
+----+-----+-------+---------------+
StockData
+----+-----+-------+------+----+
| ID | QTY |ProdID |Status|Type|
+----+-----+-------+------+----+
| 1 | 100 | 1 | 0 | 3 |
+----+-----+-------+------+----+
| 2 | 120 | 2 | 0 | 3 |
+----+-----+-------+------+----+
| 3 | 100 | 3 | 0 | 3 |
+----+-----+-------+------+----
| 4 | 200 | 1 | 0 | 4 |
+----+-----+-------+------+----+
| 5 | 200 | 2 | 0 | 4 |
+----+-----+-------+------+----+
| 6 | 48 | 1 | 0 | 2 |
+----+-----+-------+------+----+
| 7 | 96 | 2 | 4 | 3 |
+----+-----+-------+------+----+
| 8 | 200 | 1 | 4 | 4
+----+-----+-------+------+----+
ProdBiscuit ID is relational with StockData.ProdID
ProdBiscuit.StockId is relational with StockData.ID
StockData.Status = 0 => Entry in stock, > 0 =>Left the stock
Type means 2=>Macaron, 3=>Biscuit, 4=>Ganache
ProdID => ID of ProdBiscuit
StockID-> ID of StockData
With the method below I get this
+--------------+--------+---------+
|Name |QTY PROD|QTY REST |
+--------------+--------+---------+
|Bis Chocolat | 100 | 100 |
+--------------+--------+---------+
|Bis Moutarde | 120 | 24 |
+--------------+--------+---------+
|Bis Epice | 100 | 100 |
+--------------+--------+---------+
Result is correct but the query seems to me to be incorrect.
Because in WHERE clause query search the rows where status > 0
However I get the correct result??
Here is my code :
private void RefreshProd()
{
Int16 ProdQty;
Int16 UsedQty;
DateLst.Items.Clear();
ProdLst.Items.Clear();
QtyLst.Items.Clear();
NomLst.Items.Clear();
prodidLst.Items.Clear();
using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs))
{
using (MySqlCommand cmd = new MySqlCommand("SELECT tb.id, tb.qty,tb.nom, tb.proddate, IF(status > 0 AND tb.id = sd.prodid, sd.quantite, 0) AS rq FROM StockData AS sd, " + TableName + " AS tb WHERE sd.matcuisine = 3 AND sd.status > 0", conn))
{
conn.Open();
try
{
MySqlDataReader r = cmd.ExecuteReader();
while (r.Read())
{
DateLst.Items.Add(Convert.ToDateTime(r["proddate"]).ToString("d"));
ProdQty = Convert.ToInt16(r["qty"]);
UsedQty = Convert.ToInt16(r["rq"]);
ProdLst.Items.Add(r["qty"]).ToString();
NomLst.Items.Add(r["nom"]);
prodidLst.Items.Add(r["id"]).ToString();
QtyLst.Items.Add((ProdQty-UsedQty).ToString());
}
}
catch (MySqlException e)
{
MessageBox.Show("MYSQL ERROR--> " + e.ToString());
}
}
}
}
I could not find the rub.
The thing that's astonishing me that the query seems to me to be faulty but gives a correct result.
In where clause I put a condition that the search must be "sd.status>0" but it seems to me it's fetching the status = ZERO conditions too.(Perhaps I am missing something technical in MYSQL WHERE clause)
How ever bu doing my premenade overthestackflow I learnt that UNION and JOIN is more powerfull then the method that I use.
Is there a more efficient way to write my query by JOIN oro UNION? I will appreciate your help. Because I couldn't find way to resolve it by this way.
this query?
SELECT
tb.id
, tb.qty
, tb.nom
, tb.proddate
, sd.quantity as rq
FROM
StockData AS sd
INNER JOIN " + TableName + " AS tb
On tb.id = sd.prodid
WHERE
sd.matcuisine = 3
AND sd.status > 0

Categories