inner join on multiple tables in a DataSet - asp.net

I have a data set which has 2 data tables.Both these tables are retrieved from 2 distinct Oracle Databases (physically and logically separate).
I need to do a Inner Join on these two tables which reside in 1 dataset. And then display the result in a gridview.
Are there any possibilities of doing SQL Joins on tables inside a Dataset?
If yes, does anyone have a worked out example? If not, can someone point me in the right direction - I do not wish to do any "hacks" (manually looping thru and other iterations of that sorts) as I believe there will be a way to do it within the environment, just need the right approach.
This is in VB .net so would appreciate a more relevant code BUT any help is highly appreciated.

Try this method helper:
private DataTable JoinDataTables(DataTable t1, DataTable t2, params Func<DataRow, DataRow, bool>[] joinOn)
{
DataTable result = new DataTable();
foreach (DataColumn col in t1.Columns)
{
if (result.Columns[col.ColumnName] == null)
result.Columns.Add(col.ColumnName, col.DataType);
}
foreach (DataColumn col in t2.Columns)
{
if (result.Columns[col.ColumnName] == null)
result.Columns.Add(col.ColumnName, col.DataType);
}
foreach (DataRow row1 in t1.Rows)
{
var joinRows = t2.AsEnumerable().Where(row2 =>
{
foreach (var parameter in joinOn)
{
if (!parameter(row1, row2)) return false;
}
return true;
});
foreach (DataRow fromRow in joinRows)
{
DataRow insertRow = result.NewRow();
foreach (DataColumn col1 in t1.Columns)
{
insertRow[col1.ColumnName] = row1[col1.ColumnName];
}
foreach (DataColumn col2 in t2.Columns)
{
insertRow[col2.ColumnName] = fromRow[col2.ColumnName];
}
result.Rows.Add(insertRow);
}
}
return result;
}

Related

How to set dropdownlist values to datatable

There is a list of items in drop-down list.I want to add those items in data table while selecting one by one item.How to do that? here i am giving my code.
foreach (System.Web.UI.WebControls.DropDownList li in ddlAssignedTo.Items)
{
if (li.SelectedItem ==checked)
{
DataRow drUsers = dtAssigners.NewRow();
drUsers["GIMID"] = GIMID;
drUsers["MODE"] = 'I';
drUsers["UserId"] = Convert.ToInt32(li.SelectedValue);
drUsers["CreatedBy"] = CurUsr.UserId;
dtAssigners.Rows.Add(drUsers);
}
}
i am getting error near (li.SelectedItem ==checked)... can anyone help me?
Example, if your drop down is like following:
You want to add first item in your table. You can do like:
if (ddl.SelectedValue == "1")
{
//Write Your Code here
}
All these conditions will work using above DropDownList
if(ddl.SelectedValue == "1")
if(ddl.SelectedIndex == 0)
if (ddl.SelectedItem.Text == "One";
You don't need to iterate the items in a dropdown to find the selected item.
var item = ddlAssignedTo.SelectedItem;
if (item != null)
{
DataRow drUsers = dtAssigners.NewRow();
drUsers["GIMID"] = GIMID;
drUsers["MODE"] = 'I';
drUsers["UserId"] = Convert.ToInt32(item.Value);
drUsers["CreatedBy"] = CurUsr.UserId;
dtAssigners.Rows.Add(drUsers);
}
Edit: ok, if multiple items are selected, you can try this -
foreach (ListItem item in ddlAssignedTo.Items)
{
if (item.Selected)
{
}
}
Edit 2: if your drop down list has checkboxes, you are most likely using the checkboxlist control.
The following code works fine for me. Please compare how you are setting up your data table.
DataTable dt = new DataTable("table1");
dt.Columns.Add("col1");
foreach(ListItem item in CheckBoxList1.Items)
{
if (item.Selected)
{
names.Add(item.Text);
DataRow dr = dt.NewRow();
dr["col1"] = item.Text;
dt.Rows.Add(dr);
}
}

How convert stream excel file to datatable C#?

I use Epplus to reading xlsx files from stream.
It has a bug , it cant read some columns in my workbook.How can read xlsx files from stream to datatable without epplus ?
my older code:
public static DataSet ReadExcelFile(Stream stream)
{
try
{
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader =
ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
DataSet result = excelReader.AsDataSet();
return result;
}
catch (Exception x)
{
throw x;
}
}
I didnt report it, but i tried so much combinations.If there are empty columns in worksheet ,epplus reader cant read correctly column values.
"It has a bug , it cant read some columns in my workbook"
Can you describe the bug, have you reported it or is it already known, what version are you using?
Here's a simple approach to load an excel file into a DataTable with EPPlus.
public static DataTable getDataTableFromExcel(string path)
{
using (var pck = new OfficeOpenXml.ExcelPackage())
{
using (var stream = File.OpenRead(path))
{
pck.Load(stream);
}
var ws = pck.Workbook.Worksheets.First();
DataTable tbl = new DataTable();
bool hasHeader = true; // adjust it accordingly( i've mentioned that this is a simple approach)
foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
{
tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
}
var startRow = hasHeader ? 2 : 1;
for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
{
var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
var row = tbl.NewRow();
foreach (var cell in wsRow)
{
row[cell.Start.Column - 1] = cell.Text;
}
tbl.Rows.Add(row);
}
return tbl;
}
}
This is way past, however it could still help someone.
Apparently some columns in my worksheet were merged, so for example, if columns A and B are merged it only recognizes column A as the one with the value, and so it returns column B as empty, when i call on that particular cell's value(B). To get past this, make sure you know which cells are merged and then grab only the first one and regard the rest of the merged cells as null

Aggregating one side of a many-to-many and bind to gridview in Entity Framework

I have a many-to-many structure in place in my database / Entity Framework model.
CompanyNotice (M-M) CompanyNoticesLocations (M-M) Locations
I am trying to aggregate the Locations for one CompanyNotice and return a comma-separated LocationName for the Locations. I have tried using the following code to aggregate the LocationName:
if (!IsPostBack)
{
using (var context = new ALEntities())
{
var query = from c in context.CompanyNotices.Include("Locations")
select new
{
c.CompanyNoticeHeading,
c.CompanyNoticeText,
c.IsHR,
locations = (from l in c.Locations select l.LocationName).Aggregate((current, next) => string.Format("{0}, {1}", current, next))
};
ASPxGridView1.DataSource = query;
ASPxGridView1.DataBind();
}
}
I get the following error when I try the above code:
LINQ to Entities does not recognize the method 'System.String
Aggregate[String](System.Collections.Generic.IEnumerable1[System.String],
System.Func3[System.String,System.String,System.String])' method, and
this method cannot be translated into a store expression.
When I try:
if (!IsPostBack)
{
using (var context = new ALEntities())
{
var query = from c in context.CompanyNotices.Include("Locations")
select new
{
c.CompanyNoticeHeading,
c.CompanyNoticeText,
c.IsHR,
locations = (from l in c.Locations select l.LocationName)
};
ASPxGridView1.DataSource = query;
ASPxGridView1.DataBind();
}
}
The data within the locations column on the gridview appears as:
System.Collections.Generic.List`1[System.String]
Does anyone know how do I aggregate the LocationName to appear for one CompanyNotice?
Thanks in advance.
you could this ...
using (var context = new ALEntities())
{
var query = from c in context.CompanyNotices.Include("Locations")
select new
{
c.CompanyNoticeHeading,
c.CompanyNoticeText,
c.IsHR,
locations = (from l in c.Locations select l.LocationName)
};
var listed = query.ToList();
var commaListed = listed.Select ( a=> new { a.CompanyNoticeHeading, a.CompanyNoticeText,
commaLines = a.locations.Aggregate((s1, s2) => s1 + "," + s2)});
then bind commaListed to your datagrid

how do i convert IEnumerable<MyClass> to DataTable very fast?

I'm familiar with the reflection method that converts any IEnumerable to DataTable, but it's very very slow!
When i get not huge but big chunk of data i get very slow browser reaction, because it's very complicated data to handle.
I need to boost my prefformance, how do i do it?
PS: Checked LazyLoading DataTable no success there ether, maybe someone will show me how to do it?
Thank you very very much in advance.
See this artice for detailed explanation.
Core code sample
public static DataTable ToDataTable<T>(this IEnumerable<T> collection)
{
DataTable dt = new DataTable();
Type t = typeof(T);
PropertyInfo[] pia = t.GetProperties();
//Create the columns in the DataTable
foreach (PropertyInfo pi in pia)
{
if ((pi.PropertyType.IsGenericType) )
{
Type typeOfColumn = pi.PropertyType.GetGenericArguments()[0];
dt.Columns.Add(pi.Name, typeOfColumn);
}
else
dt.Columns.Add(pi.Name, pi.PropertyType);
}
//Populate the table
foreach (T item in collection)
{
DataRow dr = dt.NewRow();
dr.BeginEdit();
foreach (PropertyInfo pi in pia)
{
dr[pi.Name] = pi.GetValue(item, null);
}
dr.EndEdit();
dt.Rows.Add(dr);
}
return dt;
}
}
Why do you think that data converting slows your app? Did your profile it?

Dynamic Template Controls

On !PostBack dynamic templates are created based on the number of rows needed for check boxes. The control id's are chkbox_id. I am unable to retrieve the dynamic check boxes via the following code and NullReferenceException is always thrown.
The code before loops through the gridview rows, then datatable dt references the possible number of dynamic columns.
for (int i = 0; i < dt.Rows.Count; i++)
{
string id = dt.Rows[i]["id"].ToString();
CheckBox cb = (CheckBox)row.FindControl("ckbox_" + id);
if (cb.Checked)
{ // do things }
}
Checkboxes defined here within page load:
if (!Page.IsPostBack)
{
foreach (DataRow dRow in dt.Rows)
{
TemplateField ckhColumn = new TemplateField();
ckhColumn.HeaderTemplate = new GridViewTemplate(ListItemType.Header, dRow["name"].ToString());
ckhColumn.ItemTemplate = new GridViewTemplate(ListItemType.Item, "ckbox_" + dRow["id"].ToString());
gvProductPriceList.Columns.Add(ckhColumn);
}
}
Let me know if I need to clarify anything else.
I'm not positive on this, and I don't have a minute to try it, but it might work if you do a row.Parent.FindControl(...). Also, if you use the as operator instead of a direct cast, you won't have the null reference exception (i.e. you can check for it):
CheckBox cb = row.Parent.FindControl("ckbox_" + id) as CheckBox;
if (cb != null)
{
// ...
}

Resources