Clearing the existing collection and adding but still says - The SqlParameter is already contained by another SqlParameterCollection - sql

I am not able to figure out whats wrong with this code. i am clearing all the parameters and then adding them but it still gives me the error saying "The SqlParameter is already contained by another SqlParameterCollection."
Please help
using (SqlConnection m_Connection = Class_SetApplicationEnviroment.Get_Sql_Connection())
{
m_Connection.Open();
SqlCommand oSqlCommand = new SqlCommand(m_spName, m_Connection);
oSqlCommand.CommandType = CommandType.StoredProcedure;
if (m_Parameters.Length > 0)
{
//SQLDataAdapter.SelectCommand.Parameters.Clear();
oSqlCommand.Parameters.Clear();
foreach (SqlParameter oParam in m_Parameters)
{
if (oParam != null)
{
// Check for derived output value with no value assigned
if ((oParam.Direction == ParameterDirection.InputOutput ||
oParam.Direction == ParameterDirection.Input) &&
(oParam.Value == null))
{
oParam.Value = null;
}
oSqlCommand.Parameters.Add(oParam);
//SQLDataAdapter.SelectCommand.Parameters.Add(oParam);
}
}
}
//Execute the Stored Procedure
//SQLDataAdapter.Fill(myTable);
strReturnValue = oSqlCommand.ExecuteNonQuery().ToString();
m_Connection.Close();
}
}

As I can see your m_Parameters is a private collection of parameters in your class.
When you instance this class, and run this code for the first time, you create a command, and add the parameters of this collection to a newly created command Parameters collection.
On the second run, you create a new different command, and try to add the parameters to the new, fresh command. And, as your parameters were already attached to the old command's collection, you get taht error.
You can create a single command as a member of your class, attach the parameters to its collection and reuse it as many times as you want. Or you can create a new collcetion of parameter for each command execution. Perhaps (I'm not sure) if you run this line oSqlCommand.Parameters.Clear(); just after closing the connection, they'll be "freed up" and can be used on the next execution. You can try this first

Related

Why does Create method return empty response when instantiating UoW manually

I am creating an instance of Unit of Work manually and use it to create new row. The problem is that even though my row is created successfully, the EntityId property in SaveResponse is null. (Error property is also null)
using (var conn = sqlConnStrings.NewByKey("Default"))
{
using (var uow = new UnitOfWork(conn))
{
resp = Create(uow, req);
// resp.EntityId is null despite successful insert to DB.
uow.Commit();
}
// accessing resp variable outside the using block doesn't help.
}

Is it better to create Single or multiple SQL connection to execute same query multiple time?

I'm executing same command in every 2 seconds. I think following code creates multiple connections:
[System.Web.Services.WebMethod]
public static int getActivity()
{
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString()))
{
connection.Open();
using (var cmd = new SqlCommand("SELECT TOP 1 ValueX FROM TABLE WHERE ID= 2 AND EVENTID = 2 ORDER BY DATE DESC", connection))
{
var x = cmd.ExecuteScalar();
int Result;
if (x != null)
{
Result = int.Parse(x.ToString());
Console.WriteLine("USER ACTIVITY : " + Result);
}
else
{
Result = -999;
}
connection.Close();
return Result;
}
}
}
If I call this method several time Does following code make multi connection Or single connection ?
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnection"].ToString()))
Can someone explain whether I need to modify this code or Is this good one ?
Thanks.
Since you are using the using statement clause so once you are done with the method the resources are freed and the connection is closed. So everytime when you call the same method a new connection will be made. When you are using the using clause then it is equivalent to the below code:
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
}
finally
{
if(connection != null)
((IDisposable)connection).Dispose();
}
Also note that you dont need to explicitly call the connection.Close(); in your method as using statement will take care of it.
Your method is fine, you just don't need connection.Close() as described by Rahul. Using statement when dealing with SQL objects is good practice.
What you should keep in mind, is that ADO.NET connection pooling, takes care of handling new objects referring to the same connection string, thus minimizing the time needed to open a connection.
More about connection pooling can be found Here

Datatables: How to reload server-side data with additional params

I have a table which gets its data server-side, using custom server-side initialization params which vary depending upon which report is produced. Once the table is generated, the user may open a popup in which they can add multiple additional filters on which to search. I need to be able to use the same initialization params as the original table, and add the new ones using fnServerParams.
I can't figure out how to get the original initialization params using the datatables API. I had thought I could get a reference to the object, get the settings using fnSettings, and pass those settings into a new datatables instance like so:
var oSettings = $('#myTable').dataTable().fnSettings();
// add additional params to the oSettings object
$('#myTable').dataTable(oSettings);
but the variable returned through fnSettings isn't what I need and doesn't work.
At this point, it seems like I'm going to re-architect things so that I can pass the initialization params around as a variable and add params as needed, unless somebody can steer me in the right direction.
EDIT:
Following tduchateau's answer below, I was able to get partway there by using
var oTable= $('#myTable').dataTable(),
oSettings = oTable.fnSettings(),
oParams = oTable.oApi._fnAjaxParameters(oSettings);
oParams.push('name':'my-new-filter', 'value':'my-new-filter-value');
and can confirm that my new serverside params are added on to the existing params.
However, I'm still not quite there.
$('#myTable').dataTable(oSettings);
gives the error:
DataTables warning(table id = 'myTable'): Cannot reinitialise DataTable.
To retrieve the DataTables object for this table, please pass either no arguments
to the dataTable() function, or set bRetrieve to true.
Alternatively, to destroy the old table and create a new one, set bDestroy to true.
Setting
oTable.bRetrieve = true;
doesn't get rid of the error, and setting
oSettings.bRetrieve = true;
causes the table to not execute the ajax call. Setting
oSettings.bDestroy = true;
loses all the custom params, while setting
oTable.bDestroy = true;
returns the above error. And simply calling
oTable.fnDraw();
causes the table to be redrawn with its original settings.
Finally got it to work using fnServerParams. Note that I'm both deleting unneccessary params and adding new ones, using a url var object:
"fnServerParams": function ( aoData ) {
var l = aoData.length;
// remove unneeded server params
for (var i = 0; i < l; ++i) {
// if param name starts with bRegex_, sSearch_, mDataProp_, bSearchable_, or bSortable_, remove it from the array
if (aoData[i].name.search(/bRegex_|sSearch_|mDataProp_|bSearchable_|bSortable_/) !== -1 ){
aoData.splice(i, 1);
// since we've removed an element from the array, we need to decrement both the index and the length vars
--i;
--l;
}
}
// add the url variables to the server array
for (i in oUrlvars) {
aoData.push( { "name": i, "value": oUrlvars[i]} );
}
}
This is normally the right way to retrieve the initialization settings:
var oSettings = oTable.fnSettings();
Why is it not what you need? What's wrong with these params?
If you need to filter data depending on your additional filters, you can complete the array of "AJAX data" sent to the server using this:
var oTable = $('#myTable').dataTable();
var oParams = oTable.oApi._fnAjaxParameters( oTable );
oParams.push({name: "your-additional-param-name", value: your-additional-param-value });
You can see some example usages in the TableTools plugin.
But I'm not sure this is what you need... :-)

SSIS ScriptTask change Value property of Variable

I try to simply change value of SSIS variable doing this code in ScriptTask:
string path = Dts.Connections["BazyPobrane"].ConnectionString.ToString();
string[] nameZIParray = Directory.GetFiles(path, "*.ZIP");
string[] nameRARarray = Directory.GetFiles(path, "*.RAR");
foreach (string nameZIP in nameZIParray) //search new ZIP
{
if (File.GetCreationTime(nameZIP) > DateTime.Now.AddDays(-1))
{
Dts.Variables["User::NazwaPliku"].Value = Path.GetFileName(nameZIP);
}
}
foreach (string nameRAR in nameRARarray) //search new RAR
{
if (File.GetCreationTime(nameRAR) > DateTime.Now.AddDays(-1))
{
Dts.Variables["User::NazwaPliku"].Value = Path.GetFileName(nameRAR);
}
}
Dts.TaskResult = (int)ScriptResults.Success;
After executing ScriptTask it simply don't change the variable Value. Debug mode seems fine. Maybe i miss some component settings?
Thx!
Some things to check:
Are you sure the variable isn't changing? If you put a subsequent script task with a MessageBox in place, does it show the correct value?
I don't think you need the variable type, i.e. remove "user::"
Make sure the variable is in the ReadWriteVariables property, as suggested by #OcasoP
What's the scope of the variable? Make sure you don't have two copies at different scopes, or that at least the one you do have is visible from the scope of the script
You could try locking the variable before writing to it (which should be equivalent to (3) above)
Code example for the last point:
IDTSVariables100 variables = null;
this.VariableDispenser.LockOneForWrite("NazwaPliku",ref variables);
variables[0].Value = myValue;
variables.Unlock();
debug your script task adding MsgBox(variable_name) and see its value through the execution.
Best debugging option :)

Execute a SQL stored procedure before every query generated by EntityFramework

I need to execute a SQL stored procedure every time before I query my ObjectContext. What I want to achieve is setting the CONTEXT_INFO to a value which will be later on used with most of my queries.
Has anyone done that? Is that possible?
[EDIT]
Currently I'm achieving this by opening the connection and executing the stored procedure in my ObjectContext constructor like this:
public partial class MyEntitiesContext
{
public MyEntitiesContext(int contextInfo) : this()
{
if (Connection.State != ConnectionState.Open)
{
Connection.Open(); // open connection if not already open
}
var connection = ((EntityConnection)Connection).StoreConnection;
using (var cmd = connection.CreateCommand())
{
// run stored procedure to set ContextInfo to contextInfo
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[dbo].[SetContextInfo]";
cmd.Parameters.Add(new SqlParameter("#ci", _contextInfo));
cmd.ExecuteNonQuery();
}
// leave the connection open to reuse later
}
}
Then in my integration test:
[TestMethod]
public void TestMethod1()
{
using (var ctx = new MyEntitiesContext(1))
{
Assert.AreEqual(2, ctx.Roles.ToList().Count);
Assert.AreEqual(2, ctx.Users.ToList().Count);
}
}
But this requires me to leave the connection open - this is error prone since I will always need CONTEXT_INFO, and another developer might easily do:
[TestMethod]
public void TestMethod2()
{
using (var ctx = new MyEntitiesContext(1))
{
// do something here
// ... more here :)
ctx.Connection.Close(); // then out of the blue comes Close();
// do something here
Assert.AreEqual(2, ctx.Roles.ToList().Count);
Assert.AreEqual(2, ctx.Users.ToList().Count); // this fails since the where
// clause will be:
// WHERE ColumnX = CAST(CAST(CONTEXT_INFO() AS BINARY(4)) AS INT)
// and CONTEXT_INFO is empty - there are no users with ColumnX set to 0
// while there are 2 users with it set to 1 so this test should pass
}
}
The above means that I can write the code like in my test and everthing is green (YAY!) but then my colleague uses the code from TestMethod2 somewhere in his business logic and it's all f'd up - and nobody knows where and why since all tests are green :/
[EDIT2]
This blog post certainly does not answer my question but actually solves my problem. Maybe going with NHibernate will be better suited for my purpose :)
We have used this pattern.
But the way we did it was to call the stored procedure as the first opperation inside each db context.
Finally I found the answer. I can wrap the connection using the EFProvider wraper toolkit from EFProviderWrappers.
To do this I mostly have to derive from EFProviderWrapperConnection and override the DbConnection.Open() method. I already tried it with the Tracing provider and it works fine. Once I test it with my solution I will add more information.