I have developed a Window Service using SQL Database currently in my DB is full of Record so query execuction taking much time while default command timeout is 30S but I want to increase it to 120S one option is
com.CommandTimeout = 120;
but I have many methods in my Application so I want to set it from APP.config file so it will be applicable for Application level, can anyone please tell me how could I achive this
Thanks
The easiest way to achieve this is to add a new entry in <appSettings> something like this:
<appSettings>
<add key="commandTimeout" value="3000" />
</appSettings>
Afterwards, create a CommandFactory class that will populate the value
class CommandFactory
{
public static int CommandTimeout
{
get
{
int commandTimeout = 0;
var configValue = ConfigurationManager.AppSettings["commandTimeout"];
if(int.TryParse(configValue, out commandTimeout))
return commandTimeout;
return 120;
}
}
public static SqlCommand CreateCommand(SqlConnection connection)
{
var command = new SqlCommand()
{
Connection = connection,
CommandTimeout = CommandTimeout
};
return command;
}
}
Now, in your code, instead of just instantiating a new SqlCommand just call the CommandFactory method:
using(var command = CommandFactory.CreateCommand(yourConnection))
{
//
}
use this in app.config file
<configuration>
<appSettings>
<add key="connectioStringName" value="Data Source=source;Initial Catalog=tableName;User Id=databaseName;Password=password;Connection Timeout=3000"/>
</appSettings>
</configuration>
Related
This is a noob question but I have been stuck here for a few hours so I need to get passed this. I have this Windows App that performs a simple function. It makes a trip to the DB and checks if a specific record exists and if it does then perform some operation. However it just doesn't want to read the connection string - it comes as null all the time. I keep getting null every time I initialize my connection string. What could I be doing wrong. I only have one connection string named App.config.
Class File:
private class ClassA
{
private string myConnectionString = "";
private SqlConnection mySQLConnection;
private SqlCommand mySQLCommand;
private int CheckIfSerialNumberExists(UInt64 ColumnToCheck)
{
int countResult = 0;
myConnectionString = ConfigurationManager.ConnectionStrings["ConnectionStringName"].ConnectionString; //I get an object reference null here when the compiler executes this line. I have been using this structure for years and never got any issues
using (mySQLConnection = new SqlConnection(myConnectionString))
{
string procName = "SELECT Count(*) ColumnName FROM Table WHERE ColumnName='" + ColumnToCheck + "'";
mySQLCommand = new SqlCommand(procName, mySQLConnection);
mySQLConnection.Open();
countResult = (int)mySQLCommand.ExecuteScalar();
}
return countResult;
}
private void someFunc()
{
//Test value: 5
if(CheckIfSerialNumberExists(5) > 0)
{
//Don't do anything
}
else
{
//Save to DB
}
}
}
Config File:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="ConnectionStringName"
connectionString="Data Source=ServerName;Initial Catalog=DatabaseName;Persist Security Info=True;User ID=**;Password=****"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/></startup>
</configuration>
So here is the quick fix:
In my windows app I am referencing a class library project. I had only added the connection string in that project. I added it to my windows app project and there we go, all was working. Really feel like an idiot.
I had small c# software that works on several database on several servers and I need to switch between different schema so..
depending on the current server ip I connect to master table on specified server
and get the schema name then add as variable within the connection string by this way ..
is it safe to use this way to make connection string flexible ?
if no then what do you suggest
string oradb = "Data Source=source;User Id=" + DBSchema + ";Password=pwd;";
In general run-time parameters are to be stored outside your code and in many cases the config file is one of the best places for that. You could use a factory method to build the connection string as in CodeProject-Don't Hard Code Your Data Providers or you could write a few lines of code to set the values using the .NET connection string builder as in ConnectionStringBuilder Class.
for example currently I have a web application that 2 web forms that need 2 different connection I will show you how I have it for 1 of the 2 forms
public static string storedProcName = "NameOfSomeStoredProc";
public string ConnString
{
get { return ConfigurationManager.ConnectionStrings["DbConn2"].ConnectionString; }
}
public string UserConnName
{
get { return string.Concat(ConfigurationManager.AppSettings["userConnName"], storedProcName); }
}
the method actual stored procedure call inside a method will look like the following I am passing in the Stored Proc name based on a static storedProcName declared above..
Create yourself a Helper Class and you can have something like the following that you would call from within your Class where you are wanting to execute the code
HelperClass.cs
public static DataSet ExecuteDataSet2(string sql, CommandType cmdType, params OracleParameter[] parameters)
{
using (DataSet ds = new DataSet())
using (OracleConnection connStr = new OracleConnection(ConfigurationManager.ConnectionStrings["DbConn2"].ConnectionString))
using (OracleCommand cmd = new OracleCommand(sql, connStr))
{
cmd.CommandType = cmdType;
cmd.CommandTimeout = 60 * 22;
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
try
{
cmd.Connection.Open();
new OracleDataAdapter(cmd).Fill(ds);
}
catch (Exception ex)
{
utilities.SendErrorEmails(ex);
throw ex;
}
return ds;
}
}
Your Web.Config for example would look like this if you have 2 different DB connection string.. you would create the same method as above calling it ExecuteDataSet1.... and change the DbConn2 to DbConn and in the Public string ConnString change the DbConn2 to DbConn in your other class or have a check box and depending on the selection you can store botn ConnString get retrun .. calling your other one ConnString2 pretty straight forward
<connectionStrings>
<add name="DbConn" connectionString="Data Source={0};User Id={1};Password={2};" />
<add name="DbConn2" connectionString="Data Source={0};User Id={1};Password={2};" />
</connectionStrings>
<appSettings>
<add key="userConnName" value="NameOfOracleUser." />
</appSettings>
//Pay close attention to the . in the NameOfOracleUser., this depending how you have your procedures setup you would have OracleDbUserName.StoredProcedure name to execute.. notice in the Populate_DataGrin method I am passing the UserConnName and the string.Concat will pick up the storedProcName from this
public static string storedProcName = "NameOfSomeStoredProc"; works like a charm and if you had a dropdown of stored proc names to run.. it would work the same by assigning the name based on the drowpdown selection text..
last but not least the method / event that calls the ExecuteDataSet2 would look like this
private void Populate_DataGrin(int intMonth, string strLocation)
{
dtSomeDataTable = OracleDBHelper.ExecuteDataSet2(UserConnName, CommandType.StoredProcedure
, new OracleParameter("var_IntMonth", intMonth)
, new OracleParameter("var_StrLocation", strLocation)
, new OracleParameter
{
ParameterName = "p_cursor"
,
OracleDbType = OracleDbType.RefCursor
,
Direction = ParameterDirection.Output
}
).Tables[0];
YourDataGrid.DataSource = null;
YourDataGrid.DataSource = dtSomeDataTable;
YourDataGrid.DataBind();
}
So I have successfully add a data connection to my VS project and now I'm trying to populate the drop down menu that I created with the data from the tables coming from the database; however, when I run the code it says, "Login failed for use 'Username', on this line:
cmd.Connection.Open();
This is my C# code:
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
namespace Test1234
{
public partial class Home : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
PopulateDDList1();
//PopulateDDList2();
//PopulateDDList2_1();
}
public void PopulateDDList1()
{
SqlCommand cmd = new SqlCommand("SELECT * FROM [History]", new SqlConnection(ConfigurationManager.AppSettings["Connection"]));
cmd.Connection.Open();
SqlDataReader ddlValues;
ddlValues = cmd.ExecuteReader();
DropDownList1.DataSource = ddlValues;
DropDownList1.DataValueField = "Serial";
DropDownList1.DataTextField = "Serial";
DropDownList1.DataBind();
cmd.Connection.Close();
cmd.Connection.Dispose();
}//end Populate 1
}
}
This is the web.config code:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<add name="ActioNetITInventoryConnectionString" connectionString="Data Source=10.10.101.188;Initial Catalog=ActioNetITInventory;User ID=rails.sa;Password=ActioNet1234"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<appSettings>
<add key="Connection" value="Data Source=10.10.101.188;Initial Catalog=ActioNetITInventory;User ID=rails.sa;Password=***********;Integrated Security=True"/>
</appSettings>
</configuration>
<appSettings>
<add key="Connection" value="Data Source=10.10.101.188;Initial Catalog=ActioNetITInventory;User ID=rails.sa;Password=***********;Integrated Security=True"/>
</appSettings>
Your connection string contains both a login & password as well as Integrated Security=True
If you are trying to log on with a named login/password, then either set Integrated Security=False or leave it out altogether
I think there error occures due to your connection string. Is there a reason that you don't use the servername but its IP?
By the way: You defined it twice in two different config sections..
If you're using the IP, then you have to add the port:
Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;
Initial Catalog=myDataBase;User ID=myUsername;Password=myPassword;
Alternatively you could use the standard way:
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;
Or even better if possible: Use trusted connection:
Server=myServerAddress;Database=myDataBase;
Generally have a look here: http://www.connectionstrings.com/sql-server/
You have several potential failure points, for instance:
Calling ExecuteReader but not actually validating data, ie no Null.
Potentially several Columns being returned, when you only need a Key and Value.
Are you sure Serial is valid Column.
Your connection includes integrated security and a login / password. Use one or the other. (Kritner's answer has good information and direction for this).
To make your code a bit more legible and robust, you could do the following:
public IList<TModel> GetModel<T>(string query) where TModel : new()
{
var container = new List<T>();
using(var connection = new SqlConnection(dbConnection))
using(var command = new SqlCommand(query, connection))
{
connection.Open();
using(var reader = command.ExecuteReader())
while(reader.Read())
{
TModel model = new TModel();
var type = model.GetType();
var table = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToArray();
foreach(var property in type.GetProperties())
foreach(var column in table)
if(String.Compare(property.Name, column, true) == 0)
if(!reader.IsDBNull(reader.GetOrdinal(property.Name)))
property.SetValue(model, reader.GetValue(reader.GetOrdinal(property.Name)), null);
container.Add(model);
}
}
}
The following method will build your model, so you would simply do:
drpExample.DataSource = GetModel<Person>("SELECT * FROM [History]");
drpExample.DataBind();
You really shouldn't have a direct query like that, you should really use Parameters but this should get you started. Also you will need the DataKeyValue and DataKeyText which I often apply to the front-end. You would simply set the value to the correlated Property in your model.
As stated in my comment, you can't provide both login credentials and state integrated security=true - it's one or the other.
Integrated Security basically says "use the current domain credentials I'm logged into the system with."
That being said, you probably want it to look like this:
<add key="Connection"
value="Data Source=10.10.101.188;Initial Catalog=ActioNetITInventory;User ID=rails.sa;Password=ActioNet1234;"/>
Although the "Connection" seems redundant as you already have a connection string with the same information. You can use that like this:
SqlCommand cmd = new SqlCommand(
"SELECT * FROM [History]",
new SqlConnection(
ConfigurationManager.ConnectionStrings["ActioNetITInventoryConnectionString"].ConnectionString)
)
);
I am trying to use a button that will add to my two columns in my database. I have placeholder values in there currently but will eventually be using 2 pop ups to read in those values.
My question is: how do I get the connection string? I don't know what to put there or where to get that data.
private void button_AddPartNumber_Click(object sender, EventArgs e)
{
string cmdString = "INSERT INTO Part_Numbers (Part_Number, Barcode_Number) VALUES (#val1, #val2)";
string connectionString = "I DONT KNOW WHAT TO PUT HERE";
using (SqlCommand connection = new SqlCommand(connectionString))
{
using (SqlCommand comm = new SqlCommand())
{
comm.Connection = connectionString;
comm.CommandText = cmdString;
comm.Parameters.AddWithValue("#val1", "L-0G004-0830-xx"); //placeholder value
comm.Parameters.AddWithValue("#val2", "asdf1234"); // placehold value
}
}
} // end button_AddPartNumber_Click()
Well, what database are you using? For example, SQLServer? Oracle? MySQL?
In SQLServer, at least, the connection string is defined in the web.config, or app.config, and has syntax similar to the following:
<appSettings>
<add key="ConnectionStringName" value="AppName"/>
</appSettings>
<connectionStrings>
<add name="AppName" connectionString="Data Source=DataSourceName; Initial Catalog=DataBaseName; user id=UserID; password=Password" providerName="System.Data.SqlClient"/>
</connectionStrings>
Something like that. There's probably something I'm missing, but without testing it out in your code, I'm blanking on what that might be.
This how you extract the connection string from your code if the connection string is properly set in the web.config:
var connectionString = ConfigurationManager.ConnectionStrings["AppName"].ConnectionString;
I'm experimenting some difficulties trying to use Connection String Builders (ADO.NET) within LINQ to SQL. Let me show you guys what I'm trying to do:
the app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="LoremIpsum"
connectionString="Data Source=SomeServer;Initial Catalog=SomeDB;User ID=joe;"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
and a snippet of the form:
ConnectionStringSettings settings =
ConfigurationManager.ConnectionStrings["LoremIpsum"];
if (null != settings)
{
string connection = settings.ConnectionString;
SqlConnectionStringBuilder builder =
new SqlConnectionStringBuilder(connection);
// passwordTextBox being the control where joe the user actually
// enters his credentials
builder.Password = passwordTextBox.Text;
}
LINQTOSQLDataClassDataContext db = new LINQTOSQLDataClassDataContext();
// finally some rather anecdotic LINQ sentence here:
var foo = db.Table.Single(bar => bar.Table == whatever);
On the other hand checking the Immediate Window:
?builder.ConnectionString
"Data Source=SomeServer;Initial Catalog=SomeDB;User ID=joe;Password=swordfish"
I'm always getting an exception: Login failed for user 'joe'. Any ideas? Thanks much in advance.
It seems like you are trying to modify the connection string that is stored in the app.config file. When you use a no argument constructor for your data context, it reads what was configured at design time.
Try injecting your modified connection string into the constructor of the DataContext:
ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings["LoremIpsum"];
SqlConnectionStringBuilder builder;
LINQTOSQLDataClassDataContext db;
if (null != settings)
{
string connection = settings.ConnectionString;
builder = new SqlConnectionStringBuilder(connection);
// passwordTextBox being the control where joe the user actually enters his credentials
builder.Password =passwordTextBox.Text;
db = new LINQTOSQLDataClassDataContext(builder.ConnectionString);
} }
You're forgetting to send in the connectionstring to the DataContext constructor.
Example:
LINQTOSQLDataClassDataContext db = new LINQTOSQLDataClassDataContext(builder.ConnectionString);
You can force a DataContext to use a specific connection string with
DataContext db = new DataContext(myConnectionString);
The parameterless DataContext constructor will use a connection string from the App.config file first, then the connection string set at compile time.