I'm trying to make a dynamic connection to DB for all of my packages. I'm trying to achieve this by loading my user defined variables with a Script Component .
I know I can also use environment variables to do this, the problem is that not all of my packages will be scheduled and some of them I run with a web service or a procedure, so I can't use a scheduled job to do this, and using the #reference_id is a bit complicate to maintain.
I have no idea how can I loop the variables. I tried
foreach (Variable var in Variables)
But that's not the way ..
So I have two questions here:
How do I loop all the variables I passed?
How do I get the Variable name out of it ? (I don't see a name attribute on Variables.VarName.?)
E.G. The OLE DB source will return two rows:
conName | conString
con1 | someConnection
con2 | someConnection
And I have two user defined variables in my project -> con1 and con2 .
So, iterate through my varaibles -> foreach(variable) , if var.name = row.conName , load with row.conString value .
Finally I've managed to do this. For those of you who will want to do the same, here is what I did :
public class ScriptMain : UserComponent
{
Dictionary<string, string> AllCons = new Dictionary<string, string>();
public override void PostExecute()
{
base.PostExecute();
string connectionString;
foreach (IDTSVariable100 obj in ReadWriteVariables)
{
if (AllCons.TryGetValue(obj.QualifiedName, out connectionString))
{
obj.Value = connectionString;
}
}
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
AllCons.Add("User::" + Row.ConName, Row.ConString);
}
}
I used a Dictionary object to store the connection name and connection string on the Input0_ProcessInputRow section. Then, in the PostExecute, I've iterated through all of my User Defined Variables using an IDTSVariable100 Object. I then checked, if the connection name equals the variable, put the connection string in it.
Hope it helps someone.
Related
my application is like one application with multiple database[all databse are with same schema] i need to switch the connection on dropdown select.i am now managing the all connection string with switch case but now i need to transfer the all connection string to class[.cs] file for globally use in hole app how to do this if session is correct then how to pass string using session to class file and how to retrieve it in hole project
now my cs file is:-
public class connectionstr { static string mulcon = "";
static SqlConnection myconnection = null;
public connectionstr()
{
// // TODO: Add constructor logic here //
}
public static SqlConnection getconnection(string opt)
{
if(opt=="RV001")
{
mulcon = ConfigurationManager.ConnectionStrings["DUM01ConnectionString"].ConnectionString;
}
else if(opt=="SV001")
{
mulcon = ConfigurationManager.ConnectionStrings["CompMasterConnectionString"].ConnectionString;
}
if(myconnection==null)
{
myconnection = new SqlConnection(mulcon);
myconnection.Open();
}
return myconnection;
}
}
but i need to add this in one webform which have dropdown the we shift the connection on dropdown selection and also which connection is selected that that connection is applied with all project webforms
What you essentially need is a single repository for the entire application. You have few options -
Singleton pattern - More details here - Basically you have to implement a singleton class which acts as a store for the connection string. Keep a dictionary in the singleton class. The key in the dictionary will be the user id, and the value will be the selected connectionstring. When the user selects the connectionstring, insert into the dictionary against the user. Wherever he needs a connection, use the connectionstring from the store.
You can do the same by storing the connectionstring in a session variable. As long the user session is valid, you can retrieve it and use it.
I'm trying to return a string though a Getter, the string is obtained from a DataRead object which loops through the mysql query. The problem is that, upon load, the string does not get loaded onto the main form's label, it returns an empty string and if I assign a string to the variable upon declaration, it returns that to my main form. Here's the code:
string text;
public string Text { get { return text; } }
public void DBConn()
{
MySqlConnection conn = new MySqlConnection(connStr);
DataSet ds = new DataSet();
MySqlDataReader reader = null;
try
{
// connection to DB
reader = cmd.ExecuteReader();
if (reader != null && reader.HasRows)
{
while (reader.Read())
{
text = reader["string1"].ToString() + " " + reader["string2"].ToString() + " " + reader["string3"].ToString();
}
}
}
// try, catch. conn.close()
}
The reader is assigning the values onto text just fine, but outside of the while, the value is not assigned to the globally declared variable, it seems to get destroyed as soon as it leaves the loop. Can anyone please help?
Thank you.
Thank you to those who helped me find the solution to the problem described. As some of you kindly explained (and I was lacking the knowledge to understand at first until a lot of research was done), the issue turned out to be a problem with my Main form being in a different instance from the first class that calls upon the class that has the Getter in it. I know now I should have mentioned all of these details in the original post, I apologize to those of you who tried to understand from a small piece of code. After a lot of research on Instances, the solution I came to was to first, create a class that holds static Getters and Setters public static string Text { set; get; } (this was how I wanted it for easy access from other classes) this helps in making them accessible from all instances, it might not be the best solution especially on OOP - During my research I read somewhere that using Setters and Getters is a waste of time and not the best practice for programmers, that it is best to encapsulate but because I am still very fresh I will look up how to do that later.
Thank you guys again.
This is my syntax, but it is not being passed to my connection string, it is being omitted, which of course is causing an error as the database doesn't exist. Is it possible to do this?
namespace bottomsup
{
class onetwothree
{
private static string databaseName = null;
private static string ServerConnectionString = "Data Source=BradJohnson;Initial Catalog=" + databaseName + "DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True"";
Form1()
{
InitializeComponents();
}
private void ConnectToServerClick()
{
databaseName = textbox1.Text;
using (SqlConnection connection = new SqlConnection(ServerConnectionString))
{
connection.Open();
//more stuff
}
}
}
}
No, if you change the value of databaseName later on, it doesn't automatically change the value of ServerConnectionString.
You have to set the value of ServerConnectionString again yourself.
ServerConnectionString =
string.Format("Data Source=BradJohnson;Initial Catalog={0}DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True", textbox1.Text);
I'd avoid the static variable, as it can lead to bugs if you try to reuse it, and especially if you overwrite it, in multiple places. One place sets it, then another, and now one or the other is going to grab an incorrect value when it tries to retrieve it.
Perhaps something like this instead, where you always have to pass the database name in:
private static string GetServerConnectionString(string databaseName)
{
return string.Format("Data Source=BradJohnson;Initial Catalog={0}DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True", databaseName);
}
To use it with your existing code:
using (var connection = new SqlConnection(GetServerConnectionString(textbox1.Text)))
{
connection.Open();
//more stuff
}
I doubt if statics are justified in this case.
Nevertheless, it will not work with variable ServerConnectionString, but you could use a property instead:
private static string ServerConnectionString
{
get
{
return "Data Source=BradJohnson;Initial Catalog=" + databaseName +
"DB;User ID = pmartin;Integrated Security=True;MultipleActiveResultSets=True";
}
}
Often when you try to add a null value to something which has a value, it will fall over. In the DB Name you should use String.Empty as opposed to null.
Also I think you have an extra quote on the end of the string.
When you set the connection string, it is not going to dynamically update if you ever change the other property anyway.
I have this code that queries a database. I want to put the actual database code into a separate class so I can reuse it in other places. This will leave just the actual read of the PassResult value so I can make a Unit Test of the code without having the SQL code running. I am having trouble finding references on how to make this kind of code Unit Testable. Could someone help out?
using System;
using System.Data;
using System.Data.SqlClient;
namespace CS_UI_Final_Inspection
{
public class CalibrationTestCheck
{
// declare the variables
private bool _calibrationTestPass = false;
private string _connectionString = string.Empty;
public bool CheckCalibrationTestResults(string serialNumber, IDeviceInfo deviceInfo, string mapID)
{
// get database location
DhrLocationPull dhrLocation = new DhrLocationPull();
_connectionString = dhrLocation.PullDhrLocation();
// build the query
SqlConnection calibrationCheckConnection = new SqlConnection(_connectionString);
SqlCommand calibrationCheckCommand = new SqlCommand("[MfgFloor].[GetLatestTestResultsForDeviceByTestType]",
calibrationCheckConnection);
// build the stored proc
calibrationCheckCommand.CommandType = CommandType.StoredProcedure;
calibrationCheckCommand.Parameters.Add(new SqlParameter("#SerialNumber", serialNumber));
calibrationCheckCommand.Parameters.Add(new SqlParameter("#DeviceTypeID", mapID));
calibrationCheckCommand.Parameters.Add(new SqlParameter("#TestDataMapTypeID", "C"));
calibrationCheckCommand.Connection.Open();
SqlDataReader calibrationCheckReader = calibrationCheckCommand.ExecuteReader();
// is there data?
if (calibrationCheckReader.HasRows)
{
// read the data
calibrationCheckReader.Read();
try
{
_calibrationTestPass = (bool) calibrationCheckReader["PassResult"];
}
catch (InvalidOperationException)
{
// means last element was not filled in
}
finally
{
// close refs
calibrationCheckReader.Close();
calibrationCheckCommand.Connection.Close();
calibrationCheckConnection.Close();
calibrationCheckReader.Dispose();
calibrationCheckCommand.Dispose();
calibrationCheckConnection.Dispose();
}
}
return _calibrationTestPass;
}
}
}
create an interface and implement it.
move all references to be tested to use the interface (exposing any methods/properties required through the interface)
have the constructor or method being tested take the interface as a parameter.
Roy Oscherov is a good resource on this. Roy Oscherov wrote a great book called "The art of unit testing". Roy's website can be found here: http://osherove.com/
I have an application that I want to be able to configure the connection string for my LINQ to SQL. I've tried so many different ways but cannot seem to get it working. I want to do this dynamically in the code when the app is run, the reason for this is that the user can change the connection settings.
If I delete the connectionString out of app.config the application still works OK (communicating) which makes me wonder where I should be changing the connection string?
I think that the best way to do it is a combination of Albin's and Rup's answers. Have a value in the config file, and then read it at run time and feed it to the context constructor, something like this:
WEB.CONFIG:
<appSettings>
<add key="ConString" Value="The connection string" />
CODE:
//read value from config
var DBConnString = System.Configuration.ConfigurationManager.AppSettings("ConString");
//open connection
var dataContext= new MyDataContext(sDBConnString)
this way you can change the connection string even at runtime and it will work and change on the running program.
You can pass an override connection string into the DataContext constructor:
var db = new MyDataContext("Data Source=Something Else;")
The DBML class (YourDataContext) has an overloaded constructor which takes ConnectionString, so try instantiating that instead of the default one.Get the connection string from app.config and use that to create the instance.
YourDataContext context = new YourDataContext (ConfigurationManager.ConnectionStrings["ConnStringInAppConfig"].ConnectionString)
You should change it in app.config. The reason it works without is that the LINQ2SQL designer creates a fallback to the connection string used when designing the DBML. If you define a connection string in app.config that is used instead.
By Default your constructor look like this
public dbDataContext() :
base(global::invdb.Properties.Settings.Default.Enventory_4_0ConnectionString, mappingSource)
{
OnCreated();
}
You can change return value Instead of
//Original
public string Enventory_4_0ConnectionString {
get {
return ((string)(this["Enventory_4_0ConnectionString"]));
}
}
this
//Modified code
public string Enventory_4_0ConnectionString {
get {
return (System.Configuration.ConfigurationManager.ConnectionStrings["Enventory_4_0ConnectionString"].ConnectionString);
}
}
Inside your dbml file designer.cs add this dynamic call to base class constructor. It will work for local, dev and prod automatically pulling from current web.config without need to pass connection every time;
public HallLockerDataContext() :
base(ConfigurationManager.ConnectionStrings["MYDB1"].ConnectionString, mappingSource)
{
OnCreated();
}
Usage:
using (var db = new HallLockerDataContext())
{
}