How to set up a database in a class - c#

New C# dev here, and I'm working on my first desktop application. I have a class set up that will do all of my SQL Server CE database work. Inside of my class, I have a few static strings set up that I am using to create the database, and I will use the same connection string to connect to the database.
private static string DBFileName = "engine.msbdb";
private static string DBPassword = "msb";
private static string DBConnectionString = string.Format("DataSource=\"{0}\"; Password='{1}'", DBFileName, DBPassword);
Now comes my question. In each of my methods that I have taking actions on my database, do I need to make a new connection in each of my methods? I can't necessarily create the connection in the constructor, because the database hasn't been created yet. How would I go about using the same connection in each of my methods so I don't have to rewrite all of the code each time I need to connect to the database? Do I simply write a private method that connects to the database and returns the database connection object? Just at a loss and can't figure out where to go from here. Sorry in advance if this question is a little confusing as I am still learning how this works.

Create a property in your class for the SqlCeConnection object. Call the Open() and Close() from each method in your class that needs it.
private SqlCeConnection conn { get; set; }

If your application is small scale desktop app, nothing wrong in creating SqlConnection as a private variable within each method. Try using it within a using statement for better disposing
using (SqlCeConnection connection = new SqlCeConnection(DBConnectionString)){
connection.Open();
using (SqlCeCommand cmd = new SqlCeCommand("SELECT * FROM Emp",connection))
{
}
}
Once you get a hang of C# and DotNet in general, try to read on Repository and UnitOfWork patterns. These patterns will help you to better isolate your data access logic
Hope this helps

Related

How to have separate instance of ASP.NET dataset for each API call?

I have a project that is already developed using dataset in Visual Studio, and I want to use the same datasets for CRUD transactions for my newly developed web app.
When two users try to add a new record exactly at the same time, it happens that the record is inserted into another database. For instance instead of saving that record in table x of DB1, it is saved in table x of db2.
Here is the code for instantiating the dataset:
[System.Web.Http.HttpOptions]
[System.Web.Http.HttpPost]
[System.Web.Http.Route("api/PayAndReceive/AddForm")]
public string AddForm([FromBody] FormList MdlObject)
{
clsConnectionString clnn = new clsConnectionString(MdlObject.BaseParams[0].ToString().Trim(), MdlObject.BaseParams[1].ToString());
Z.DAL.DataSetAlls.D1DataTable datatable1 = new Zeus.DAL.DataSetAlls.D1DataTable();
Z.DAL.DataSetAllsTableAdapters.D1TableAdapter adapter1 = new Z.DAL.DataSetAllsTableAdapters.D1TableAdapter();
Here is the class:
public class clsConnectionString
{
public string ConnectionStringIS = "";
private void SetConnectionString(string CorporationID, string FisCalYear)
{
string ServerName = System.Configuration.ConfigurationManager.AppSettings["ServerName"].ToString();
string ISDbName = "DB" + "" + CorporationID + "" + FisCalYear;
ConnectionStringIS = "Data Source=" + "" + ServerName + ";" + "Initial Catalog =" + "" + ISDbName + ";" + "Integrated Security = True" + ";";
Z.DAL.SetConnectionString cls = new Z.DAL.SetConnectionString();
cls.setISDBConnectionString =
}
}
There are other places in the code that same table and adapter is created and I have added setting connection string before all of them, in order to make sure they are using correct database for table creation.
Is it a correct way of creating a datatable in an api?
Is it ok to have ConnectionStringIS as a public variable or it may make a problem when it is used in an api?
Does dataTable1 and Adapter1 will be connected to new db when another api call happens and that causes the issue?
Any advice would be appreciated.
any chance you using a static class for this?
You can't make/create/set/have/use a static class for persisting this data set.
You can certainly have a whole bunch of static helper routines, and a libary of code as static and that is fine.
but, you certainly don't want to have nor use a static class for connections, or the datasets.
So, you posted this:
Z.DAL.DataSetAlls.D1DataTable datatable = new
Zeus.DAL.DataSetAlls.D1DataTable();
Z.DAL.DataSetAllsTableAdapters.D1TableAdapter adapter = new
Z.DAL.DataSetAllsTableAdapters.D1TableAdapter();
The above looks fine, as LONG as you not attempting to persit the dataset in a static class. Static classes are shared among all users of the web site.
So, say in a page on load, if the above code is say in that page class, then you are fine.
However, if the above code is global - in some static class, then you can't do that, since static class(s) if global persisted are shared amoung all users.
So, say I want to fill a grid view? (and I not using the pre Entitfy Framework dataset designer, or the newer EF data designer)?
Then I am free to do this:
Say, I want to load a gridview, then this is fine:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
string strSQL = "SELECT * FROM People ORDER BY Family_ID, FamilyType DESC";
SqlCommand cmdSQL = new SqlCommand(strSQL);
GridView1.DataSource = General.MyRstP(cmdSQL);
GridView1.DataBind();
}
so, in above, note how I don't crete a "instance" of class General. "Genreal" is my shared libary code - all kinds of helper routines in that static class.
So, MyRstP is this:
public static DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
Again, note how that routine creates a connection object. But, as such, it not global to the class "general", and thus it is multi-user safe.
So, your posted code looks fine, but only if that posted code is not part of a static class that attempts to persist the values global to that class.
And it not all that clear why you have more then one connection to the database, and that such connections are "different" for each user. That's not a normal approach here, and especially when using dataset designer, or the newer Entity Frameworks. They REALLY do not work if you design assuming is to have multiple connections for that EF or dataset designer active at the same time.
In other words?
You really can't on the fly change the active connection for the dataset designer, or the EF designer since such connections are going to be persisted, and you can't have multiple active connections at the same time.
as a FYI:
The term and use of "dataset" in above has ZERO ZERO to do with the type object called datatable, or dataset (which is a collection of tables).
While it is VERY but VERY rare to have multiple active connections for the SAME tables in a given applcation? You can certainly have multiple database connections active, but not for a single given EF and not for the DS designer.
You can get away with such a less than ideal design for desktop applications, since each desktop has their own copy of running code. On a web site, you have ONE copy of the code, and all logged on users share that code. A new instance of running code is not created for each new user who logs into the site.
So any public vars to a static class are in fact shared among all users. But, of course as my above General class example shows, each routine is free to create instances of objects - even connection objects. but, you certainly cannot have public vars global to the static class, since as noted, you NOT creating an instance of that class when it is used by all logged on users.
So all functions (methods) of the class are fine for that static class, but you can't adopt nor use public vars in that class, since you never creating a instance of the class.
It not clear if you are creating a connection object or those datasets inside of a static class. If you are then simply don't make that class static, and thus in your code you can simple create a instance of that class, including the public connection object and even the public datasets in that class. But, that class can't be static.
So, if you need multiple different connections? then don't use a static class to hold that connection and datasets information, and you should be fine.
Edit
In your sample code you don't show how and where you are setting the connection- we need to see that code.

Entity Framework Seems to want to use Sql Server Provider despite needing Sql CE

I am using an SqlCe 4 database with an Entity Framework 6 code first data model.
I set the connection string in the DbContext constructor like so:
private static readonly string DATABASE_PASSWORD = "...";
private static readonly string CONNECTION_STRING = string.Format(#"Data Source={0};Password={1}", MyProject.Properties.Settings.Default.DatabaseLocation, DATABASE_PASSWORD);
public DataModel()
: base(CONNECTION_STRING)
{
}
And when I run my application which uses this model it works.
In the designer in Visual Studio however it keeps freezing for about 30 seconds at a time when I try to view a WPF control that load a set of records in the View model constructor and I get an error message as follows:
Error 2 Unable to complete operation. The supplied SqlConnection does not specify an initial catalog or AttachDBFileName.
I am not using SqlServer I am using Sql Server Compact so there should be no need to even think about using Sql Server.
Can anyone see anything wrong with my connection string?
Viewing the error message ( ...The supplied SqlConnection.. ) I conclude that you are setting an SQlConection rather than SQlCeConnection
Make sure you set your SQL object like:
conn = new SqlCeConnection(CONNECTION_STRING);
conn.Open();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = "..."
And make sure you have added a reference to the SQL Server Compact provider, System.Data.SqlServerCe.dll

Problems connecting to a local MySQL database using C# and .NET 2.0

Newb questions incoming.
I'm running MySQL locally and I am having a really hard time connecting to it with C#.
Here's the code I'm using, much of the stuff I've tried out is commented out:
using System;
using System.Collections.Generic;
//using System.Data.Common.DbConnection;
using System.Threading;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Threading;
namespace mvpde
{
class Program
{
class DataReader_SQL
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
try
{
OleDbConnection con = new OleDbConnection(#"Provider=sqloledb;Data Source=127.0.0.1:3306;database=database_name;User id=id;Password=password;");
con.Open();
//Thread.Sleep(9999);
//SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
//builder.DataSource = "localhost";
//builder.UserID = "hello";
//builder.Password = "password";
//builder.InitialCatalog = "db_123";
//SqlConnection thisConnection = new SqlConnection(builder.ToString());
//thisConnection.Open();
//SqlCommand thisCommand = thisConnection.CreateCommand();
//thisCommand.CommandText = "SELECT CustomerID, CompanyName FROM Customers";
//SqlDataReader thisReader = thisCommand.ExecuteReader();
//while (thisReader.Read())
//{
// Console.WriteLine("\t{0}\t{1}", thisReader["CustomerID"], thisReader["CompanyName"]);
//}
//thisReader.Close();
//thisConnection.Close();
}
catch (SqlException e)
{
Console.WriteLine(e.Message);
Thread.Sleep(9999999);
}
}
}
}
}
I've copied it nearly verbatim and tried to make it work from this site.
I have installed the MySQL on Windows 7 - I have created the user and the database I'm trying to access and I can do all this just fine using MySQL's own MySQL Workbench 5.2 CE software. I seem to have no clue what I'm doing using C# to connect to it.
All I want is to connect to it and send it a simple query like "USE DATABASE somedb" and then "SELECT TABLE sometable".
Errors I'm getting:
At first (when I used WAMP, before installing the MySQL package from mysql website) I would be able to connect once and see a login error; after that, it's as if the connection wasn't closed properly and I'd be unable to get even that far)
Now that I'm trying to connect to a MySQL instance that is created by MySQL's own software (or by running mysqld.exe) all I ever get is timeout problems\server not found\inaccessible.
Questions:
Am I using the wrong class?
What's the deal with "Provider="? where is the list of all the available variables for that part of the string? What does it mean? Why are the names involved so cryptic?
I imagined connecting to a locally-running MySQL server should be a breeze, but I've no idea what I'm doing.
Thank you.
You should use the MySql/Connector for DotNet.
Download it at this address then change your connection string accordingly.
For example "Server=127.0.0.1;Database=database_name;Uid=id;Pwd=password;Port=3306"
For other options, specific for MySQL, look at www.connectionstrings.com
have you had a look at http://www.connectionstrings.com/mysql ?
You can't use a SQL Connection object. You need a MySQL Connection object which is available in this library.http://www.connectionstrings.com/mysql
Download the MySQL Connection Library and use one of their connection strings provided on the site.
using MySql.Data.MySqlClient;
MySqlConnection myConnection = new MySqlConnection;();
myConnection.ConnectionString = myConnectionString;
myConnection.Open();
//execute queries, etc
myConnection.Close();
Then use the connection object to initalise the connection string and connect to MySQL

How Pass ADODB Connection object from VB Components to C# with asp.net application

I am executing multiple vb6 components that accesses different database engines such as access (mdb), sql server, etc from within asp.net.
These components are already compiled dlls in vb6 and added as referenced assembly in asp.net framework 2.0. Each component has several functions that passes the adodb.connection object as parameter and executes sql statements from within these functions. This is comparable to a layered solution pattern, only, in the business logic layer they pass the adodb.connection object instead of the connection string. This works in VB6 but when called in asp.net it won't work because when the compiler encounters the adodb.connection.open() it modifies the value of the adodb.connection.connectionstring property.
How I get connection string from adodb.connection object
EDIT
Here's the getConnstringfromASP from comments.
public void getConnstringfromASP(ADODB.Connection getadoObjConn)
{
string strAdoobjConnString = "";
strAdoobjConnString = getadoObjConn.ConnectionString;
SqlConnection objConnection = new SqlConnection();
objConnection.ConnectionString = strAdoobjConnString;
}
I think your code for creating the connection string should look something like this:
public void getConnstringfromASP(ADODB.Connection getadoObjConn)
{
string strAdoObjConnString = getadoObjConn.ConnectionString;
SqlConnection objConnection = new SqlConnection(strAdoObjConnString);
}
the connection string is passed in the constructor of the SqlConnection object.

How do I Programmatically change Connection String un LINQ C# Winforms

This question may be redundant, but i could not totally understand how to do this.
I need to be able to, when the users Run my Winforms app, can search for the instance of SQL if the previous one are not available. I already have the check for the DB existence, and also made a dialog wich search for all the available instance, and bulding the connection string isn't a problem. The point here is that, I need to be able to everytime the users open the app it loads the CN from a external file, and if the external file doesn't exist or the instance isn't available, i can use the app in another instance (asuming, offcourse, that the required DB is in that Instance).
The point is that, i don't know how to Programmatically change Connection String, using LINQ in winforms.
Thanks in advance
You should be to pass the connection string to the DataContext constructor.
var db = new MyDataContext(myconnectionstring);
var someConnectionString = "This is my connection String";
using (var db = new SomeConcreteDataContext(someConnectionString)){
//...Do whatever...
}
A DataContext is created per 'unit of work'.
As ichiban says pass the required connection string into the constructor when creating the DC

Categories