Storing and retrieving datatable from session - c#

How to store a datatable in session and to retrieve the values from the session in c#.net?

Add a datatable into session:
DataTable Tissues = new DataTable();
Tissues = dal.returnTissues("TestID", "TestValue");// returnTissues("","") sample function for adding values
Session.Add("Tissues", Tissues);
Retrive that datatable from session:
DataTable Tissues = Session["Tissues"] as DataTable
or
DataTable Tissues = (DataTable)Session["Tissues"];

To store DataTable in Session:
DataTable dtTest = new DataTable();
Session["dtTest"] = dtTest;
To retrieve DataTable from Session:
DataTable dt = (DataTable) Session["dtTest"];

You can do it like that but storing a DataSet object in Session is not very efficient. If you have a web app with lots of users it will clog your server memory really fast.
If you really must do it like that I suggest removing it from the session as soon as you don't need the DataSet.

this is just as a side note, but generally what you want to do is keep size on the Session and ViewState small. I generally just store IDs and small amounts of packets in Session and ViewState.
for instance if you want to pass large chunks of data from one page to another, you can store an ID in the querystring and use that ID to either get data from a database or a file.
PS: but like I said, this might be totally unrelated to your query :)

A simple solution for a very common problem
// DECLARATION
HttpContext context = HttpContext.Current;
DataTable dt_ShoppingBasket = context.Session["Shopping_Basket"] as DataTable;
// TRY TO ADD rows with the info into the DataTable
try
{
// Add new Serial Code into DataTable dt_ShoppingBasket
dt_ShoppingBasket.Rows.Add(new_SerialCode.ToString());
// Assigns new DataTable to Session["Shopping_Basket"]
context.Session["Shopping_Basket"] = dt_ShoppingBasket;
}
catch (Exception)
{
// IF FAIL (EMPTY OR DOESN'T EXIST) -
// Create new Instance,
DataTable dt_ShoppingBasket= new DataTable();
// Add column and Row with the info
dt_ShoppingBasket.Columns.Add("Serial");
dt_ShoppingBasket.Rows.Add(new_SerialCode.ToString());
// Assigns new DataTable to Session["Shopping_Basket"]
context.Session["Shopping_Basket"] = dt_PanierCommande;
}
// PRINT TESTS
DataTable dt_To_Print = context.Session["Shopping_Basket"] as DataTable;
foreach (DataRow row in dt_To_Print.Rows)
{
foreach (var item in row.ItemArray)
{
Debug.WriteLine("DATATABLE IN SESSION: " + item);
}
}

Related

How to use a SSIS Dataset inside Dataflow Script component for Source?

I'm looking for a way to use my Dataset variable in Script component of SSIS data flow task, here is what I tried till now
My First Task is Execute SQL task (CData PostgreSQL Task)
This would run a Postgre query and store the result in a variable User::resultSet which is of the data type DataSet
My Second Task is Data Flow Task
In my second task I wish to use the dataset as my source. I tried to achieve this by using Script Component (Source)
My Script
public override void CreateNewOutputRows()
{
DataTable dt = (DataSet)Variables.resultSet;
// The DataTable is now ready to use! No more recordset quirks.
foreach (DataRow dr in dt.Rows)
{
// Add a new output row for this transformed data.
OrdersBuffer.AddRow();
// Now populate the columns
OrdersBuffer.id = int.Parse(dr["id"].ToString());
OrdersBuffer.created = int.Parse(dr["created"].ToString());
OrdersBuffer.modified = int.Parse(dr["modified"].ToString());
}
}
Issue
In my Script, I cant figure out a way to convert the dataset into a datatable,
I believe the problem line is DataTable dt = (DataSet)Variables.resultSet; in my script
I also tried DataTable dt = resultSet.Tables[0]; & DataTable dt = resultSet.Table[0]; but all them are throwing syntax error.
Any lead or guidance will be really appreciated.
Try this one
DataTable dt = (Variables.resultSet as DataSet).Tables[0];
May throw an exception if type cast is not possible.
I have not used the dataset variable type but I have dont this with an OBJECT type variable and MS SQL DB. If you can change to use object variable this should work for you (or maybe if you cant you can see how I am passing the OBJECT variable and update your code to access the variable in similar way.
First I run a SQL task that has a result set as output in SSIS to my OBJECT variable data type. Then I pass it to my script task like this:
Inside the C# Script task I have this below code to access the OBJECT variable and then covert it to a data table that I use later on
Where this variable is my object variable type in the SSIS Package:
User::ObjDataToSaveToExportFile
// this gets the data object and sets ti to a data table
OleDbDataAdapter A = new OleDbDataAdapter();
System.Data.DataTable dt = new System.Data.DataTable();
A.Fill(dt, Dts.Variables["User::ObjDataToSaveToExportFile"].Value);
// for test data
//DataTable sourceTable = GetTestData();
DataTable sourceTable = dt;
You can use below approach of using DataAdapter to fill datatable. Reference Article
public override void CreateNewOutputRows()
{
// Set up the DataAdapter to extract the data, and the DataTable object to capture those results
OleDbDataAdapter da = new OleDbDataAdapter();
DataTable dt = new DataTable();
// Extract the data from the object variable into the table
da.Fill(dt, Variables.resultSet);
// Since we know the column metadata at design time, we simply need to iterate over each row in
// the DataTable, creating a new row in our Data Flow buffer for each
foreach (DataRow dr in dt.Rows)
{
// Add a new output row for this transformed data.
OrdersBuffer.AddRow();
// Now populate the columns
OrdersBuffer.id = int.Parse(dr["id"].ToString());
OrdersBuffer.created = int.Parse(dr["created"].ToString());
OrdersBuffer.modified = int.Parse(dr["modified"].ToString());
}

How to access Object SSIS variable inside script task?

I have SSIS variable of type object which holds the OLE DB result set from OLE DB source.
The object is list of blogs with each blog having attributes title and description.
How can I parse the SSIS object variable and iterate over each blog and then field?
EDIT :
I want to read full result set in script task.
// this gets the data object and sets ti to a data table
OleDbDataAdapter A = new OleDbDataAdapter();
System.Data.DataTable dt = new System.Data.DataTable();
A.Fill(dt, Dts.Variables["User::SSISObjectVariableFromPackage"].Value);
// for test data
DataTable sourceTable = dt;
//Now loop through databale and do your processing
//----------------------------------------------------------------------
//Updated -- possible solution to fix issue in comments but left original above as that works for most
//try this version instead, mabye converting the SSIS variable to a C# object first, and not accessing it directly into the A.Fill may resolve your issue in the comments:
Object OBJDataTableValidFieldListFull = Dts.Variables["User::SSISObjectVariableFromPackage"].Value;
// this gets the data object and sets ti to a data table
OleDbDataAdapter A = new OleDbDataAdapter();
System.Data.DataTable dt = new System.Data.DataTable();
A.Fill(dt, OBJDataTableValidFieldListFull);
// for test data
DataTable sourceTable = dt;
//Now loop through databale and do your processing

How to get particular DataTable using TableName?

One DataSet usually has lots of DataTable, but I'm only to target a particular DataTable which I thought it's pretty normal but apparently failed to do it?
Below were the approaches I've tried:
//Could not find an implementation of the query pattern for source type.......
DataTable dt = from table in changesDataSet.Tables
where table.TableName = "ABC"
select table;
//Surprisingly there was no method "Where" in changesDataSet.Tables
DataTable dt = changesDataSet.Tables.Where(x=>x.TableName="ABC").First();
Below was the code that able to print each and every table. I know I can do it via a loop but please tell me loop isn't the only options
foreach(DataTable table in changesDataSet.Tables)
{
Console.WriteLine(table.TableName);
}
You can access the table using an indexer on the collection of tables (DataTableCollection):
DataTable dt = changesDataSet.Tables["ABC"];

DataTable.Clear() method affect detached row

I'm trying to do something like this to create copy of a typed datarow:
var desRow = dataTable.NewRow();
var sourceRow = dataTable.Rows[rowNum];
desRow.ItemArray = sourceRow.ItemArray.Clone() as object[];
But when I call dataTable.Clear() method it clears all fields in desRow. How to create a deep copy of a DataRow?
In your code when you create your new row you create with that row a reference to the dataTable and that is why it clears all fields.
You can work with a data table clone, that way you will have a deep copy.
DataTable dt = ...
DataTable cloneDt = dt.Clone();
DataRow row = cloneDt.Rows[number];
dt.Rows.Clear();
dt.Rows.Add(row);
This way you will have your original data table with only the selected row.

Update a single row in DataTable

tl;dr:
I want to update ONE DataTable row and then re-cache this whole DataTable(The DataTable not just the row) so I can use it later on
I'm using a cache to store a large DataTable that I've filled with a SqlAdapter based on my MSSQL database
I use this cache to get the DataTable then use it to display a table inside a webpage, nothing odd here.
But this DataTable contains a list of users and I want to be able to edit these users(edit them in the MSSQL database that is) which is easy to do.
The issue is that after each SQL Update you have to re-cache the DataTable(otherwise it'll only be updated in the database but not in the DataTable/webpage) and since it is very large it's very annoying and makes the very simple user update take a very long time since it'll also have to a SQL SELECT to get all posts and then re-cache it
Because of this I want to update that specific row in the DataTable directly after doing my SQL update, this way I don't have to re-fetch the whole SQL table (It is the SQL SELECT part that takes a while since it is so large)
So far I've done this
//We just updated our user, now we'll fetch that with SQL and put it in a new fresh DataTable(that contains just that one row) - since this is much faster than getting the whole table
//Then we'll use that DataTable containing one fresh row to update our old DataTable and re-cache it
DataTable newDataTable = getUserByID(userID); //Get our just edited DataTable row
DataTable cachedDataTable = getSetUserCache(); //Get our cached DataTable
DataRow oldRow = cachedDataTable.Select(string.Format("id = {0}", userID)).FirstOrDefault(); //Get the old row that contains the correct ID
string test = oldRow["status"].ToString(); //Contains the old and cached value before it got edited
oldRow = newDataTable.Rows[0]; //Update the old row with the new row
string test2 = oldRow["status"].ToString(); //Now it contains the new edited value
//Here I should update the cachedDataTable with the new row updated row
DataRow oldRowAfterUpdated = cachedDataTable.Select(string.Format("id = {0}", userID)).FirstOrDefault(); //Get the old row that now should be updated but isn't
string test3 = oldRowAfterUpdated["status"].ToString(); //Still contains the old and cached value before it got edited
success = updateUserCache(cachedDataTable); //Update the DataTable cache that we'll be using later on
I only see posts on how you update the rows, but how do you actually update the DataTable itself with the new row?
Solution :
cachedDataTable.Select(string.Format("id = {0}", userID)).FirstOrDefault().ItemArray = newDataTable.Rows[0].ItemArray;
I think that you may use ItemArray property of DataRow:
void Main()
{
DataTable tableOld = new DataTable();
tableOld.Columns.Add("ID", typeof(int));
tableOld.Columns.Add("Name", typeof(string));
tableOld.Rows.Add(1, "1");
tableOld.Rows.Add(2, "2");
tableOld.Rows.Add(3, "3");
DataTable tableNew = new DataTable();
tableNew.Columns.Add("ID", typeof(int));
tableNew.Columns.Add("Name", typeof(string));
tableNew.Rows.Add(1, "1");
tableNew.Rows.Add(2, "2");
tableNew.Rows.Add(3, "33");
tableOld.Rows[2].ItemArray = tableNew.Rows[2].ItemArray; //update specific row of tableOld with new values
//tableOld.Dump();
}

Categories

Resources