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?
Related
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;
}
I want to save all record exist in a DataTable into my database. I am using Linq-to-SQL in C#.
I am using this code:
DataTable dt = null;
dt = getTable(fl.ToString()); //getting DataTable
using (DataClassesDataContext dc = new DataClassesDataContext())
{
foreach (var mt in dc.Mapping.GetTables())
{
if (dt.TableName == mt.TableName)
{
//How to insert this table values in DB??
}
}
}
Please suggest me better way to do that.
Thanks in advance.
Well, the whole point of using something like Linq-to-SQL is the fact that it gives you proper .NET objects to work with, instead of the clumsy, untyped DataTable.
So if you use Linq-to-SQL properly, you should retrieve your data as .NET objects using Linq-to-SQL, then you should modify your .NET objects, and use Linq-to-SQL again to store the data.
Something like this:
// set up your Linq-to-SQL DataContext
using (AdventureWorksDataContext ctx = new AdventureWorksDataContext())
{
// get some data - use the *OBJECTS* returned to you! Not a DataTable!
List<Customer> customers = ctx.Customers.Take(10).ToList();
// modify data
foreach (Customer c in customers)
{
c.ModifiedDate = DateTime.Now;
}
// save the changes
ctx.SubmitChanges();
}
So if you have a DataTable, what I'd suggest is converting those DataRows into some kind of an object type that's stored in your database, and then storing that information into the database using Linq-To-SQL - something like this:
public void SaveData(DataTable table)
{
// set up your Linq-to-SQL DataContext
using (AdventureWorksDataContext ctx = new AdventureWorksDataContext())
{
// iterate over the data rows
foreach (DataRow row in table.Rows)
{
// Convert the DataRow to an object
YourObjectType myData = ConvertDataRowToObject(row);
// add this data to the Linq-to-SQL data context
ctx.YourObjectTypes.InsertOnSubmit(myData);
}
// save the changes
ctx.SubmitChanges();
}
}
I have a web page that needs to update multiple records. This page gets all the information and then begins a transaction sending multiple UPDATE queries to the data base.
foreach row
{
Prepare the query
Hashtable Item = new Hashtable();
Item.Add("Id", Id);
Item.Add("Field1", Field1);
Item.Add("Field2", Field2);
Item.Add("Field3", Field3);
...
}
Then we launch the ytransaction
DO CHANGES()
public void execute_NonQuery_procedure_transaction(string StoredProcedure, List<Hashtable> Params)
{
using (MySqlConnection oConnection = new MySqlConnection(ConfigurationManager.AppSettings[DB]))
{
MySqlTransaction oTransaction;
bool HasErrors = false;
oConnection.Open();
oTransaction = oConnection.BeginTransaction();
try
{
MySqlCommand oCommand = new MySqlCommand(StoredProcedure, oConnection);
oCommand.CommandType = CommandType.StoredProcedure;
oCommand.Transaction = oTransaction;
foreach (Hashtable hParams in Params)
{
oCommand.Parameters.Clear();
IDictionaryEnumerator en = hParams.GetEnumerator();
while (en.MoveNext())
{
oCommand.Parameters.AddWithValue("_" + en.Key.ToString(), en.Value);
oCommand.Parameters["_" + en.Key.ToString()].Direction = ParameterDirection.Input;
}
oCommand.ExecuteNonQuery();
}
}
catch (Exception e)
{
HasErrors = true;
throw e;
}
finally
{
if (HasErrors)
oTransaction.Rollback();
else
oTransaction.Commit();
oConnection.Close();
}
}
}
Is there another way to do this or this is the most efficient way?
It depends on the situation, like if you have multiple row updates or adding new rows or deleting some rows or a combination of these, which modifies the database table then, the efficient way to do this is to have Batch Update...
Please go through this link Batch Update
Hope this helps...
it looks fine to me, you could eventually do not clear the Command.Parameters list but just assign the values on following iterations but probably this leads to no visible improvements.
pay attention your throw is wrong, in C# don't use throw e; but simply throw;.
{
--
public static IEnumerable<Datarow> Codes(string topvalue)
{
DataTable itemCodes = new DataTable();
itemCodes.Columns.Add("itemId");
itemCodes.Columns.Add("itemCode");
itemCodes.Rows.Add(0, firstCallingCode);
DataTable Codes = GetAllItems().Tables[0];
foreach (DataRow item in Codes.Rows)
{
if (item["ItemCode"] != DBNull.Value)
{
itemCodes.Rows.Add(item.Field<int?>("itemId"), item.Field<string>("itemCode"));
}
}
return itemCodes.AsEnumerable();d
}
how can i bind it to dropdownlist: i tried this
ddcodes.datasource = codes.getenumerable();
ddcodes.databind();
when i do this i get error about typecast. i can not solve it tried a lot please help.
my method is actually this
public static IEnumerable"Datarow" Codes(string topvalue)
dont know why editor took that datarow off. bracket and datarow.
You just need to pass in the return value from the Codes method.
ddcodes.datasource = Codes();
ddcodes.databind();
You don't need to "get" an enumerable. The Codes method is already returning one.
enter code herehi. i am trying to implment custom paging in datalist control .
and i am using Pagedatasource to schive this one
PagedDataSource objPage = new PagedDataSource();
try
{
datatable ds= (datatable)viewstate["dtimages"]
objPage.AllowPaging = true;
//Assigning the datasource to the 'objPage' object.
objPage.DataSource = ds.Dataset.Tables["Gallery"].ToString();
//Setting the Pagesize
objPage.PageSize = 8;
dlGallery.DataSource = objPage;
dlGallery.DataKeyField = "Image_ID";
**dlGallery.DataBind();// getting error**
}
catch(Exception ex)
{
throw ex;
}
Cannot compute Count for a data source that does not implement ICollection.
why is this happening does any one can help me out
thank you
You're setting your Data Source to a string by calling ToString().
It should be:
objPage.DataSource = ds.Dataset.Tables["Gallery"];