Create columns in Linq By using Looping - c#

I using the linq to left join another data table, this make me need to using Linq to create columns for new leftjoin data table.
Is it anyway to loop through the columns to create it automatically in linq?
var Dt1JoinDt2 = from dr1 in dt1.AsEnumerable()
join dr2 in dt2.AsEnumerable()
on dr1.Field<Int64>(id1) equals dr2.Field<Int64>(id2) into joinDt1AndDt2
from leftjoin in joinDt1AndDt2.DefaultIfEmpty()
select dtJoinedTable.LoadDataRow(new object[]
{
dr1.Field<String>("id"),
dr1.Field<Int64?>("col_sample"),
dr1.Field<String>("col2"),
dr1.Field<String>("colName"),
dr1.Field<String>("columns"),
dr1.Field<String>("col_no"),
......
This is the portion of code I want to use loop to create the columns
dr1.Field<String>("id"),
dr1.Field<Int64?>("col_sample"),
dr1.Field<String>("col2"),
dr1.Field<String>("colName"),
dr1.Field<String>("columns"),
dr1.Field<String>("col_no"),
......
Is it anyway to do this by Linq or C# or others coding method???

I think you still need to cast to DataColumn
using System.Data
var Dt1JoinDt2 = from dr1 in dt1.AsEnumerable()
join dr2 in dt2.AsEnumerable()
on dr1.Field<Int64>(id1) equals dr2.Field<Int64>(id2) into joinDt1AndDt2
from leftjoin in joinDt1AndDt2.DefaultIfEmpty()
select dtJoinedTable.LoadDataRow(
(from dc1 in dt1.Columns.Cast<DataColumn>() select dc1.ColumnName).ToArray() // cast to DataColumn, use joinDt1AndDt2
.Union((from dc2 in dt2.Columns.Cast<DataColumn> select dc2.ColumnName).ToArray())
)

I don't have a computer in hand but you can try something like:
dt1.Columns.AsEnumerable().Select(column => dr1[column.Name]).ToArray()

Related

Linq join table and create dynamic column error

I would like to do something create dynamic column in Linq for my joined table.
This is my code after asking around. But it give me another error like this.
Code:
var SelectedDT1AndDt2= from dr1 in dt1.AsEnumerable()
join dr2 in dt2.AsEnumerable()
on dr1.Field<Int64>("id1") equals
dr2.Field<Int64>("id2") into joinDt1AndDt2
from leftjoin in joinDt1AndDt2.DefaultIfEmpty()
select dtJoinedTable.LoadDataRow(
(from dc1 in dt1.Columns.Cast<DataColumn>()
select dc1.ColumnName.ToString()).ToArray()
.Union(from dc2 in dt2.Columns.Cast<DataColumn>()
select dc2.ColumnName).ToArray()
, false);
SelectedDT1AndDt2.CopyToDataTable();
Error:
Input string was not in a correct format.Couldn't store in id Column. Expected type is Int64.
This is because the column import is not type Int'64', I check again and confirm that the original col type is Int'32'.

C# Linq Table query to count the non-matching entries

I am quite new to this, I am running two SQL queries and I am creating two separate data tables, DataTable1 and DataTable2.
I am applying some linq criteria to DataTable1 and creating another data table from that, which is DataTable3.
var Query3 = from table1 in DataTable1.AsEnumerable()
where table1.Field<DateTime>("DateTime") <= Yday
where table1.Field<string>("StockCode").Contains("-CA") && !(table1.Field<string>("StockCode").Contains("-CAB")) ||
table1.Field<string>("StockCode").Contains("-CM") ||
table1.Field<string>("StockCode").Contains("-LP")
select table1;
DataTable DataTable3 = Query3.CopyToDataTable()
Now I would write another query to do the following.
Both data tables have a column JobNumber. I would like to query DataTable3 in DataTable 2 to count the rows that have similar JobNumber entries. Below is what I am doing but I am not getting the correct count.
int count = (from table3 in DataTable3.AsEnumerable()
join table2 in DataTable2.AsEnumerable() on table2.Field<string>("JobNumber") equals table3.Field<string>("JobNumber")
where table2.Field<string>("JobNumber") == table3.Field<string>("JobNumber")
select table2).Count();
You are creating a cartesian join and counting its result, was that what you indented ? Also in your linq your Join expression and where expression is same (where is redundant). It is not clear what you really want to count. Probably you instead wanted to count those in DataTable2 where JobNumbers exists in DataTable3?:
var jobNumbers = (from r in DataTable3.AsEnumerable()
select r.Field<string>("JobNumber")).ToList();
var count = (from r in DataTable2.AsEnumerable()
where jobNumbers.Contains( r.Field<string>("JobNumber") )
select r).Count();
As a side note, it would be much easier if you used Linq To SQL instead (rather than Linq To DataSet).

How to select all columns in LINQ Datatable join?

var collection = from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable()
on t1["id"] equals t2["id"]
select new { Name = t1["name"], Group = t2["group"] };
I want to select all columns of both table like join in SQL Server inner join query.
In Addition
How can i convert whole result of both tables to data-table?
var collection = from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable()
on t1["id"] equals t2["id"]
select new { T1 = t1, T2 = t2 };
then...
EDIT:
Something along those lines
//clone dt1, copies all the columns to newTable
DataTable newTable = dt1.Clone();
//copies all the columns from dt2 to newTable
foreach(var c in dt2.Columns)
newTable.Columns.Add(c);
//now newTable has all the columns from the original tables combined
//iterates over collection
foreach (var item in collection) {
//creates newRow from newTable
DataRow newRow = newTable.NewRow();
//iterate the columns, gets values from either original table if column name is there
foreach(var c in newTable.Columns)
newRow[c.ColumnName] = item.T1.ContainsColumn(c.ColumnName) ? item.T1[c.ColumnName] : item.T2[c.ColumnName];
newTable.Rows.Add(newRow);
}
This will work. But if dt1 and dt2 share multiple columns with the exact same name, you might have some loss of data.
While you can't expand them to columns, you can simply return the entities. Eg:
select new { CTLJCRJOB, CTLRFDSTM }
If you need it flattened, then you will have to write out the mapping yourself, but will still be very trivial.
Referenced from:
Select All columns for all tables in join + linq join
ou have to specify each manually if you want to project into a flattened type. Your other option is to just have your combined type contain both objects, and the objects will naturally bring along their properties.
select new
{
Object1 = object1,
Object2 = output
};
And you would work with it like myObj.Object1.Property1, myObj.Object2.Property4, etc.
One final option that still involves some manual work is to define an appropriate type and have a constructor or a builder method that does the work of segmenting out your object properties into a flattened type. You still perform the manual mapping, but you isolate it from your query logic.
select new CombinedType(object1, output);
//or
select builder.GetCombinedType(object1, output);
Referenced From
Select all columns after JOIN in LINQ
var collection = (from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable()
on t1 ["id"] equals t2 ["id"]
select new { Name = t1 ["name"], Group = t2 ["group"] }).ToList() ;
Hope this will help

getting non matched values from two Datatable

Is there any direct method for getting non matched values from two data table. I have one datatable which returns all the groups from Active Directory, and another datatable consist of all the group names from sharepoint list. But i need the non matched values by comparing these two datatables. please help me, if it possible.
Thanks in advance.
You could use DataRowComparer to compare the rows.
For instance, to compare the first rows of 2 data tables:
DataRow left = table1.Rows[0];
DataRow right = table2.Rows[0];
IEqualityComparer<DataRow> comparer = DataRowComparer.Default;
bool bEqual = comparer.Equals(left, right);
You can use .Except to do this. (Assuming an ID column)
IEnumerable<int> idsInDataTableA = dataTableA.AsEnumerable().Select(row => (int)row["ID"]);
IEnumerable<int> idsInDataTableB = dataTableB.AsEnumerable().Select(row => (int)row["ID"]);
IEnumerable<int> difference = idsInDataTableA.Except(idsInDataTableB );
I want compare DataTable1 that not exist in DataTable2
You can use Linq. Very efficient approaches are Enumerable.Except or Enumerable.Join(as LEFT OUTER JOIN) which are using sets:
var keyColRows = dt1.AsEnumerable()
.Select(r => r.Field<int>("KeyColumn")
.Except(dt2.AsEnumerable().Select(r2 => r2.Field<int>("KeyColumn"));
foreach(int inTable2Missing)
Console.WriteLine(inTable2Missing);
or the Join approach selecting the whole DataRow:
var rowsOnlyInDT1 = from r1 in dt1.AsEnumerable()
join r2 in dt2.AsEnumerable()
on r1.Field<int>("KeyColumn") equals r2.Field<int>("KeyColumn") into groupJoin
from subRow in groupJoin.DefaultIfEmpty()
where subRow == null
select r1;
Here you can use rowsOnlyInDT1.CopyToDataTable to create a new DataTable of the rows in table1 which are unique/new or use foreach to enumerate them.

Select Distinct from DataTable using Linq and C#

I need to select distinct records from a data table using linq and C# and I can't seem to get the syntax correct. I have the following code, which returns all the rows in a data table, how do I just return DISTINCT rows?
DataTable dt = ds.Tables[0];
var q = from dr in dt.AsEnumerable() select dr;
You'll need to use DataRowComparer
IEnumerable<DataRow> distinctRows =
dt.AsEnumerable().Distinct(DataRowComparer.Default);
More info on comparing data rows using linq to dataset can be found here
We could have:
var q = (from dr in dt.AsEnumerable() select dr).Distinct(DataRowComparer.Default);
But really, the from x in ... select x is redundant, so we can have:
var q = dt.AsEnumerable().Distinct(DataRowComparer.Default);
But all AsEnumerable() will do most of the time, is either nothing (if it's already as such) or potentially slow things up (if distinct could be processed better elsewhere), so it's normally better to do:
var q = dt.Distinct(DataRowComparer.Default);
Though there are cases where the former beats the latter.
(from dr in dt.AsEnumerable() select dr).Distinct();

Categories