Nested for loop breaks to Linq - linq

I'm pretty new to Linq and I am having troubles with creating the Linq equivalent of the below nested for loops:
for(int i = 0; i < toCompare1.Length; i++)
{
bool isUnique = true;
for(int j = 0; j < toCompare2.Length; j++)
{
if(toCompare1[i].Contains(toCompare2[j]))
{
isUnique = false;
break;
}
}
if(isUnique == true)
{
uniqueValues.Add(toCompare1[i]);
}
}
Currently, my draft code is something like this:
var unique =
from c1 in toCompare1
from c2 in toCompare2
where !c1.Contains(c2)
select c1;
But it duplicates the entries I want to have.
Can anyone help me with this?
Thanks!

In fluent syntax:
toCompare1.Where(item => !toCompare2.Any(item2 => item.Contains(item2)))
In query sytax:
from item1 in toCompare1
where !toCompare2.Any(item2 => item1.Contains(item2))
select item1;

Related

LINQ Group by with dynamic multiple parameters to splits datatable as multiple datatables in C#

I want to split datatables from one datatable by dynamic column name.
Now dynamic column names is not work.
for (int i = 0; i < nameList.Count; i++)
{
// a = r["a"]
b += nameList[i] +"="+ "r[\"" + nameList[i] + "\"]";
if (i != nameList.Count - 1)
{
b += ",";
}
}
for (int i = 0; i < nameList.Count; i++)
{
dataTableList = dtDataList.AsEnumerable().GroupBy(row
=> new { b}).Select(row => row.CopyToDataTable()).ToList();
}
}

Best and easiest way to export all the data from a datatable to an excel to get it downloaded using C#?

Using C#, which is the best and easiest way to export all the data from a datatable to an excel to get it downloaded?
I use Microsoft Interop.
Here is some sample code to get you started.
There are probably hundreds of tutorials which are better than the below. I have removed much of the code I use so I doubt the following will compile, but with careful reading, and some investigation into tutorials, you should be able to accomplish what you need.
public static void ExportToExcel(DataSet dsTodo, string strPathToSaveFile)
{
try
{
int numSteps = (dsTodo != null ? dsTodo.Tables.Count * 2 : 1);
Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
Workbook xlWorkbook = ExcelApp.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
if (dsTodo.Tables.Count > 0)
{
for (int i = dsTodo.Tables.Count; i > 0; i--)
{
Sheets xlSheets = null;
Worksheet xlWorksheet = null;
//Create Excel Sheets
xlSheets = ExcelApp.Sheets;
xlWorksheet = (Worksheet)xlSheets.Add(xlSheets[1], Type.Missing, Type.Missing, Type.Missing);
System.Data.DataTable table = dsTodo.Tables[i - 1];
xlWorksheet.Name = table.TableName;
for (int j = 1; j < table.Columns.Count + 1; j++)
{
ExcelApp.Cells[1, j] = table.Columns[j - 1].ColumnName;
}
var excelData = new object[table.Rows.Count, table.Columns.Count];
for (int rowJ = 0; rowJ < table.Rows.Count; rowJ++)
{
for (int colI = 0; colI < table.Columns.Count; colI++)
{
excelData[rowJ, colI] = table.Rows[rowJ][colI];
}
}
int startCol = 1;
int endCol = startCol + table.Columns.Count - 1;
int startRow = 2;
int endRow = startRow + table.Rows.Count - 1;
string startLoc = GetCellFromCoords(startCol, startRow);
string endLoc = GetCellFromCoords(endCol, endRow);
//ExcelApp.get_Range(startLoc, endLoc).Value2 = excelData;
try
{
Range valRange = ExcelApp.get_Range(startLoc, endLoc);
valRange.Value2 = excelData;
}

how to get static range in your report

In AX Report the User can select different Range. I seek to show that the criteria used to filter user in the report itself even
the expression "parameter!CustomerAccount.Value" don't work because this filter is not a static parameter.
the user can use any table from the query and any field from the table and any criteria.. I'm locking for trick to get for which table, which field and what criteria it uses.
this method work very well ^_^
(( I use it privet and not static ))
static void getQueryRanges2(Args _args)
{
Query query;
QueryRun queryRun;
QueryBuildDataSource qbd;
QueryBuildRange range;
QueryFilter filter;
int cnt, filtercnt, i,j, k;
DictTable dictTable;
DictField dictField;
str fieldLabel;
;
query = new query(queryStr(smmSalesCustItemStatistics));
queryRun = new QueryRun(query);
queryRun.prompt();
query = queryRun.query(); for(i = 1; i <= query.dataSourceCount(); i++)
{
cnt = query.dataSourceNo(i).rangeCount();
filtercnt = 0;
if(!query.dataSourceNo(i).embedded())
{
filtercnt = query.queryFilterCount(query.dataSourceNo(i));
}
dictTable = new DictTable(query.dataSourceNo(i).table());
for (k=1; k<= filtercnt; k++)
{
filter = query.queryFilter(k, query.dataSourceNo(i));
dictField = new DictField(query.dataSourceNo(i).table(), fieldname2id(query.dataSourceNo(i).table(), filter.field()));
info (strFmt("%1, %2. Range = %3", dictTable.label(), dictField.label(), filter.value()));
}
for (j=1; j<=cnt; j++)
{
range = queryRun.query().dataSourceNo(i).range(j);
dictField = new DictField(query.dataSourceNo(i).table(), fieldname2id( query.dataSourceNo(i).table(), range.AOTname()));
if(range.value())
{
info(strfmt("%1, %2. Range = %3",dictTable.label(), dictField.label(), range.value()));
}
}
}
}
enjoy :)

Sorting a DataTable using LINQ

I have a DataTable which has the following structure.
StartDate (Type DateTime)
EndDate (Type DateTime)
Description (Type Text)
What I need to check is if the dates overlap or not, i.e., if the Start Date of 1 item is less than the EndDate of the previous item.
Here is the code I wrote.
NB: I already have checks to ensure that for each record, the Start Date has to be lesser than the End Date
dtDates.DefaultView.Sort = "StartDate ASC"; //Sort the DataTable based on the Start Dates
if(dtDates.Rows.Count > 1) //Check only if more than 1 Date is specified
{
for (int i = 1; i < dtDates.Rows.Count; i++)
{
if(TypeConvert.ToDate(dtDates.Rows[i]["StartDate"] < TypeConvert.ToDate(dtDates.Rows[i-1]["EndDate"])
{
retVal = true;
currentRow = i;
break;
}
}
}
The above code works fine.
But now, I want to implement it using LINQ
So, here is the code I am trying to attempt.
How can I do the whole comparison using LINQ?
public static bool CheckIfDatesOverlap(DataTable dataTable)
{
bool retVal = false;
int currentRow = 0;
List<DataRow> listDates = (from DataRow dgv in dataTable.Rows
select dgv).OrderBy(x => x[StartDate]).ToList();
if (listDates.Count > 1) //Perform Comparision only if more than 1 row is present
{
for (int i = 1; i < listDates.Count; i++)
{
if (TypeConvert.ToDateTime(listDates[i][StartDate]) < TypeConvert.ToDateTime(listDates[i][EndDate]))
{
retVal = true; //There are duplicates, hence return true
currentRow = i;
break;
}
else
{
//Do nothing as dates do not overlap
}
}
}
else
{
retVal = false; //As there is only 1 row, return false
}
if (retVal)
{
string message = "Dates Overlap";
//Display message
}
return retVal;
}
If you use SelectWithPrevious described here then you can write the following:
bool datesOverlap = table.Rows
.Cast<DataRow>()
.SelectWithPrevious((current, previous) => new
{
PreviousEndDate = (DateTime)previous["EndDate"],
StartDate = (DateTime)current["StartDate"]
})
.Any(x => x.StartDate < x.PreviousEndDate);

split one big datatable to two separated datatables

I´m exporting datatables to Excel workbook. Problem is that the datatable holds 90000 rows and excel can only hold 67000 rows in every sheet.
So..
How can i divide one big datatable to two datatables, maybe with Linq ?
Then i can have datatable1 in sheet1 and datatable2 in sheet2
Sincerly
agh
Assuming that you're getting the 90,000 rows for this DataTable from a database somewhere, the most efficient approach would be to modify your SELECT statement into two new SELECT statements, each of which returns < 67,000 rows, and then do everything else the same.
Split your recordset. Perform one SELECT that extracts all 90,000 rows, and split it on Excel import step.
private List<DataTable> CloneTable(DataTable tableToClone, int countLimit)//Split function
{
List<DataTable> tables = new List<DataTable>();
int count = 0;
DataTable copyTable = null;
foreach (DataRow dr in tableToClone.Rows)
{
if ((count++ % countLimit) == 0)
{
copyTable = new DataTable();
copyTable = tableToClone.Clone();
copyTable.TableName = "Sample" + count;
tables.Add(copyTable);
}
copyTable.ImportRow(dr);
}
return tables;
}
protected void LinkReport_Click(object sender, EventArgs e)
{
DataTable dt2 = (DataTable)ViewState["dtab"];
List<DataTable> dt1 = CloneTable(dt2, 5);
DataSet ds = new DataSet("dst");
for (int i = 0; i < dt1.Count; i++)
{
ds.Tables.Add(dt1[i]);
}
string filePath = Server.MapPath("Reports/").ToString() + "master.xls";
FileInfo file = new FileInfo(filePath);
if (file.Exists)
{
file.Delete();
}
Export(ds, filePath);// Export into Excel
}
Clone - The fastest method to create tables with original columns structure is Clone method.
Export into Excel
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
}
finally
{
GC.Collect();
}
}
public void Export(DataSet ds, string filePath)
{
string data = null;
string columnName = null;
int i = 0;
int j = 0;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
//Excel.Worksheet xlWorkSheet;
Excel.Worksheet xlWorkSheet = null;
object misValue = System.Reflection.Missing.Value;
Excel.Range range;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Add(misValue);
//xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int l = 0; l < ds.Tables.Count; l++)
{
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(l + 1);
xlWorkSheet.Cells[1, 1] = "Report";
xlWorkSheet.get_Range("A1:D1", Type.Missing).Merge(Type.Missing);
xlWorkSheet.get_Range("A1", "D1").Font.Bold = true;
xlWorkSheet.Cells.Font.Name = "Courier New";
if (l == 0)
{
xlWorkSheet.Name = "Sheet1";
}
else if (l == 1)
{
xlWorkSheet.Name = "Sheet2";
}
else if (l == 2)
{
xlWorkSheet.Name = "Sheet3";
}
else if (l == 3)
{
xlWorkSheet.Name = "Sheet4";
}
else if (l == 4)
{
xlWorkSheet.Name = "Sheet5";
}
for (i = 0; i <= ds.Tables[l].Rows.Count - 1; i++)
{
for (j = 0; j <= ds.Tables[l].Columns.Count - 1; j++)
{
columnName = ds.Tables[l].Columns[j].ColumnName.ToString();
xlWorkSheet.Cells[3, j + 1] = columnName;
data = ds.Tables[l].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 5, j + 1] = data;
}
}
}
//for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
//{
// for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
// {
// data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
// xlWorkSheet1.Cells[i + 1, j + 1] = data;
// }
//}
xlWorkBook.SaveAs(filePath, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
// kill all excel processes
Process[] pros = Process.GetProcesses();
for (int p = 0; p < pros.Length; p++)
{
if (pros[p].ProcessName.ToLower().Contains("excel"))
{
pros[p].Kill();
break;
}
}
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
Try this One.. I have Worked out in Visual Studio 2005
DataTable[] splittedtables = dt.AsEnumerable()
.Select((row, index) => new { row, index })
.GroupBy(x => x.index / Input From User) // integer division, the fractional part is truncated
.Select(g => g.Select(x => x.row).CopyToDataTable())
.ToArray();
This should work.

Resources