Dynamic Convert Row to Column in Linq - c#

I want to convert Row to Column, actually I can implement a Static row to column as below, but it only works if I know the row position beforehand, so does anyone know how to dynamically convert a Row to Column in Linq?
This is the below table
ItemCode LOC001 LOC002 LOC003
AAA 10 11 12
BBB 13 31 14
CCC 15 18 0
This is the Static Code:
var table=(from x in Mst_LocationItems
group x by x.ItemCode into gr
select new
{
ItemCode=gr.Key,
LOC001 = gr.Where(x=>x.LocationID == "LOC001").Sum(x=>x.Reorder),
LOC002 = gr.Where(x=>x.LocationID == "LOC002").Sum(x=>x.Reorder),
LOC003 = gr.Where(x=>x.LocationID == "LOC003").Sum(x=>x.Reorder)
}).ToList();
table.Dump();

Related

llbl gen group by with conditional sum could not bound an Error

I am using linq query with llblgen and it's give me an error, anyone can please help me to resolved this issue. This is my query
var reuslt = from cc in _metadata.TableName
where cc.StdId == 125
group cc by new { cc.Column1, cc.Column2 } into gr
select new
{
Col1 = gr.Key.Column1,
Col2 = gr.Key.Column2,
IncomeType1 = gr.Sum(x => x.TypeId == 1 ? x.MonthlyIncome : 0),
IncomeType2 = gr.Sum(x => x.TypeId == 2 ? x.MonthlyIncome : 0)
};
And Error that occuring in this query when i do result.ToList()
Error:
The multi-part identifier "LPLA_3.TypeId" could not be bound.
The multi-part identifier "LPLA_3.MonthlyIncome" could not be bound.
This is data
Id stdId column1 column2 TypeId MonthlyIncome
1 125 1234 12 1 4
2 125 1235 12 2 4
Expected Output should be
StdId column1 column2 TypeId1 TypeId2 IncomeType1 IncomeType2
125 1234 12 1 2 4 4
please help me

How to get records with the same specific column content from a DataTable using LINQ

I have a table with personal data which looks something like this:
Identifier Name Phone Address
.............................
1 aa 23 abc
2 bb 22 abd
2 cc 11 aaa
3 dd 44 amd
4 fa 33 agd
2 ds 14 dad
3 as 55 fgg
I want to get the records with the same identifier, using LINQ, to get something like this
Identifier Name Phone Address
.............................
2 bb 22 abd
2 cc 11 aaa
2 ds 14 dad
3 dd 44 amd
3 as 55 fgg
I could order by Identifier and copy to a new DataTable, then parse it and get the records with the same identifier, but that would be expensive i guess. Is there a shorter way ?
Thank you !
Something like the code below would filter and extract the duplicates to a new DataTable with the same schema. Code assumes Identifier is an int. Replace with the appropriate names and types, as applicable.
var extractedDuplicates = (from row in table.AsEnumerable()
group row by row.Field<int>("Identifier") into rows
where rows.Count() > 1
from row in rows
select row).CopyToDataTable();
Give it a try and see how far that gets you. If there is any chance there aren't any duplicates, you will want to split this into multiple statements, as CopyToDataTable() will throw if there are no rows to copy.
var duplicateRows = from row in table.AsEnumerable()
group row by row.Field<int>("Identifier") into rows
where rows.Count() > 1
from row in rows
select row;
DataTable extractedDuplicates;
if (duplicateRows.Any())
extractedDuplicates = duplicateRows.CopyToDataTable();
else
extractedDuplicates = table.Clone();
And, of course, if you do not need a new DataTable, omit the second portion of this code entirely and just work with duplicateRows.
select * from YourTable a where a.Identifier in
(
select aa.Identifier from YourTable aa group by aa.Identifier
having (count(aa.Identifier ) > 1)
)

Datatable group by sum

in a Queue i have datatables in the following format
some table in the Queue
Name Rank
AAA 9
BBB 5
CCC 1
DDD 5
some other table in the Queue
Name Rank
AAA 1
SSS 5
MMM 1
DDD 8
using LINQ need to process those tables table by table continously and add the results to a global DataTable in the following format:
Name Rank1 Rank2 Rank3 Rank>3
AAA 1 0 0 1
BBB 0 0 0 1
CCC 1 0 0 0
DDD 0 0 0 2
SSS 0 0 0 1
MMM 0 0 0 0
in the global table 4 columns state how many times a name was ranked in ranks 1,2,3 or >3.
now if the name already exists in global table i will not add it but only increment the rank count columns, and if does not exist then add it.
i've done this with nested looping but i wonder if anyone can help me with the LINQ syntax to do such thing,also will using LINQ make the process faster than with nested looping?
note that new tables are added to the Queue every second and i will be getting sometable from the Queue and process it to the global datatable
table1.AsEnumerable().Concat(table2.AsEnumerable())
.GroupBy(r => r.Field<string>("Name"))
.Select(g => new {
Name = g.Key,
Rank1 = g.Count(x => x.Field<int>("Rank") == 1),
Rank2 = g.Count(x => x.Field<int>("Rank") == 2),
Rank3 = g.Count(x => x.Field<int>("Rank") == 3),
OtherRank = g.Count(x => x.Field<int>("Rank") > 3)
}).CopyToDataTable();
You will need implementation of CopyToDataTable method where Generic Type T Is Not a DataRow.
A little optimized solution (single parsing and single loop over grouped ranks):
(from row in table1.AsEnumerable().Concat(table2.AsEnumerable())
group row by row.Field<string>("Name") into g
let ranks = g.Select(x => x.Field<int>("Rank")).ToList()
select new {
Name = g.Key,
Rank1 = ranks.Count(r => r == 1),
Rank2 = ranks.Count(r => r == 2),
Rank3 = ranks.Count(r => r == 3),
OtherRank = ranks.Count(r => r > 3)
}).CopyToDataTable();

Populating an ObservableCollection of ObservableCollection, delimited by two database columns

My database is as follows :
ID Date Number NumberIWishToRecord
What I wish to do is use a Linq-to-SQL query to populate an ObservableCollection<ObservableCollection<CustomClass>>.
What I want is select only the rows were Number == a given parameter.
ID refers to a person, what I want to do is get all the information about a person and store it in an ObservableCollection, so I will have an ObservableCollection<CustomClass>, with each CustomClass holding information about only one row, and each ObservableCollection<CustomClass> holding information about only one person (recorded on different days).
I then wish to select an ObservableCollection of the ObservableCollection<CustomClass> which will hold information on all people!
So, some sample data :
ID Date Number NumberIWishToRecord
1 27-06-2012 0.1933 25
1 28-06-2012 0.1933 27
1 29-06-2012 0.1933 29
2 14-06-2012 0.1933 412
2 15-06-2012 0.1741 321
So when I run my method, I want to return only the Numbers of the given parameter, in my case I will choose 0.1933.
I then want both rows where ID = 1 to be saved in an ObservableCollection<CustomClass>, and the single row where ID == 2 to be saved in another ObservableCollection<CustomClass>. Then, both of these ObservableCollections will be held in their own ObservableCollection! To illustrate :
ObservableCollection<ObservableCollection<CustomClass>>
ObservableCollection<CustomClass>
1 27-06-2012 0.1933 25
1 28-06-2012 0.1933 27
1 29-06-2012 0.1933 29
ObservableCollection<CustomClass>
2 14-06-2012 0.1933 412
How would I write a query in linq to sql that would do this ?
I'll just write a standard query syntax Linq expression to achieve this, you adapt it for your tables.
var rowsById = new ObservableCollection<ObservableCollection<row>>(
from r in _rows
where r.number == 1.2
group r by r.ID into rowIdGroup
select new ObservableCollection<row>(rowIdGroup));
If you need to convert data from the row into the CustomClass:
var rowsById = new ObservableCollection<ObservableCollection<CustomClass>>(
from r in _rows
where r.number == 1.2
group r by r.ID into rowIdGroup
select new ObservableCollection<CustomClass>(
rowIdGroup.Select(r => new CustomClass
{
ID = r.ID,
Number = r.number // add more
})));
Or if you prefer query syntax in all the expression:
var rowsById = new ObservableCollection<ObservableCollection<CustomClass>>(
from r in _rows
where r.number == 1.2
group r by r.ID into rowIdGroup
select new ObservableCollection<CustomClass>(
from gr in rowIdGroup select new CustomClass
{
ID = gr.ID,
Number = gr.number
}));

Summary row with LINQ

I have table like this:
title row1 row2
'p1' 3 4
'p2' 23 43
'p3' 21 23
and I want to have additional summary row in this table:
title row1 row2
'p1' 3 4
'p2' 23 43
'p3' 21 23
'total' 47 70
how to do that in simple way with LINQ? I have many columns so query like that:
Row r = new Row();
r.row1 = list.Sum(x=>x.row1);
r.row2 = list.Sum(x=>x.row2);
is not good idea (in my opinion)...
You can combine it into a single LINQ query like this:
var result = row
.Select(r => r)
.Union(new Row[]
{
new Row
{
Title = "total",
Row1 = row.Sum(r => r.Row1),
Row2 = row.Sum(r => r.Row2)
},
});
But ultimately you are still individually summing the rows. I can't think of a way around that.
I can't see an obvious way of improving on what you're suggesting
var total = new List<Row>{new Row{
title="total",
row1=rows.Sum(r1=>r1.row1),
row2=rows.Sum(r2=>r2.row2)
}};
var q = rows.Concat(total);

Categories