Sqlite database utilites class - c#

I am using SQlite as a database in a C# winforms application.
My project involves some select simple queries, inserts, deletes.
Currently, I have written all these sql, Ado.net queries in the codebehind.
For eg:
private void frmPlant_Load(object sender, EventArgs e)
{
FillData();
}
void FillData()
{
dataGridView1.AutoGenerateColumns = true;
string query = #"SELECT * FROM [Table1]";
using (SQLiteConnection conn = new SQLiteConnection(connString))
{
conn.Open();
da = new SQLiteDataAdapter(query, conn);
ds = new DataSet();
da.Fill(ds, "T1");
dt = ds.Tables[0];
dataGridView1.DataSource = ds;
dataGridView1.DataMember = "T1";
dataGridView1.Columns["TId"].HeaderText = "SNo";
dataGridView1.Columns["Tcode"].Visible = false;
dataGridView1.Columns["TID"].Width = 50;
dataGridView1.Columns["Tcode"].Width = 70;
}
}
I have quiet a bit of code like this which interacts with the DB.
Question: Instead of writing these ado.net connections, sql query in the code behind, I want to use a 2 tier/3tier architecture. This should involve writing all the database stuff(ado.net execute scalar, reader, sql queries in another DBUtilitesclass/project and simply calling this DBUtilitesclass from the code behind.
Please suggest any tutorials to do this.
PS: I am using sqlite which does not support stored procedures.
Thank u
Sun

Refer
http://www.switchonthecode.com/tutorials/csharp-tutorial-writing-a-dotnet-wrapper-for-sqlite
http://snipplr.com/view/41708/
http://www.codeproject.com/Articles/22165/Using-SQLite-in-your-C-Application
Hope this helps
Thanks
Deepu

Related

Datagridview data populating on 1 machine but not another C# (Win Forms)

I have 2 laptops that both have visual studios. I have the exact program on both computers and the Datagridview is only populating on one of them, when its the exact code on both computers. Datagridview is getting populated from SQL Server, which is being hosted on a sever. Both computers have Visual Studio. I am not getting any errors. Not sure if the code is wrong or not, but I'm really trying to understand why it would only be working on 1 computer if its the same code.
I'm trying to populate the datagridview and be able to select a date and it will only show data associated with that date.
This is the code - cargoBoardDate is a datetime picker:
private void GetCargoBoard(string command)
{
var calander = cargoBoardDate.Value.ToShortDateString();
DataTable dt = new DataTable();
SqlDataAdapter da;
connection.Open();
string sql = "SELECT * FROM CargoBoard WHERE DateID LIKE #DateID";
using (var cmd = new SqlCommand(sql, connection))
{
cmd.Parameters.AddWithValue("#DateID", "%" + calander + "%");
connection.Close();
connection.Open();
da = new SqlDataAdapter(cmd);
da.Fill(dt);
da.Dispose();
dgvCargoBoard.DataSource = dt;
connection.Close();
}
connection.Close();
}
private void CargoBoard_Load(object sender, EventArgs e)
{
GetCargoBoard("SELECT * FROM CargoBoard");
HeaderDesign();
hideColumn();
RenameHeader();
formSize();
}
Also my connection string is being called from a class (below):
SqlConnection connection = new SqlConnection(Helper.conString("LoadPlanner"));
I have also tried having the parameter line as such:
cmd.Parameters.AddWithValue("#DateID", calander);
If someone could explain to me what is going on for it to work on 1 machine but not another with the exact code and a possible solution?
Thank you!

connect to tableau postgresql in C#

I want to connect to the tableau PostgreSQL server from my .Net framework to list all the reports and datasources published in the tableau server.
For doing this, I have done the following steps.
Added the npgsql.dll reference that i downloaded online
Added the below two namespaces in my class file
using NpgsqlTypes;
using Npgsql;
I added the connection sting as follows
I also tried with modifying the connection string with port value and renaming the DataSource to Server, Initial catalog to Database and provider Name to Npgsqll
My Method is as follows:
public DataTable getAllDataSourceNames()
{
DataTable dataSourceNames = new DataTable();
NpgsqlConnection conServer = new NpgsqlConnection(conString);
conServer.Open();
string command = #"select * from datasources";
NpgsqlDataAdapter sqlcmd = new NpgsqlDataAdapter(command,conServer);
sqlcmd.Fill(dataSourceNames);
return dataSourceNames;
}`
No error. I can build and run successfully the other links in the website. But cannot cannot establish connection to my postgresql server.
Any idea of how to establish the connection?
Working with Postgres Connection in c#:
private DataSet ds = new DataSet();
private DataTable dt = new DataTable();
public Form1()
{
InitializeComponent();
}
private void llOpenConnAndSelect_LinkClicked(object sender,
LinkLabelLinkClickedEventArgs e)
{
try
{
// PostgeSQL-style connection string
string connstring = String.Format("Server={0};Port={1};" +
"User Id={2};Password={3};Database={4};",
tbHost.Text, tbPort.Text, tbUser.Text,
tbPass.Text, tbDataBaseName.Text );
// Making connection with Npgsql provider
NpgsqlConnection conn = new NpgsqlConnection(connstring);
conn.Open();
// quite complex sql statement
string sql = "SELECT * FROM simple_table";
// data adapter making request from our connection
NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
// i always reset DataSet before i do
// something with it.... i don't know why :-)
ds.Reset();
// filling DataSet with result from NpgsqlDataAdapter
da.Fill(ds);
// since it C# DataSet can handle multiple tables, we will select first
dt = ds.Tables[0];
// connect grid to DataTable
dataGridView1.DataSource = dt;
// since we only showing the result we don't need connection anymore
conn.Close();
}
catch (Exception msg)
{
// something went wrong, and you wanna know why
MessageBox.Show(msg.ToString());
throw;
}
}
The following link may help you: Using PostgreSQL in your C# .NET application
Short answer -- no, not sure what's wrong. Your code doesn't raise any alarm bells.
Somewhat related, and it may help: I'm a big fan of the Connection StringBuilder with Npgsql. Here is a brief example:
NpgsqlConnectionStringBuilder sb = new NpgsqlConnectionStringBuilder();
sb.ApplicationName = "Tableau " + Environment.GetEvironmentVariable("USERNAME");
sb.Host = "1.2.3.4";
sb.Port = 5432;
sb.Username = "foo";
sb.Password = "bar";
sb.Database = "postgres";
sb.Pooling = false;
sb.Timeout = 120;
conServer = new NpgsqlConnection(sb.ToString());
It demistifies all of this and makes injecting parameters easy. I highly recommend you add the ApplicationName property so that when you are monitoring sessions, you will know who is who.

Update the datatable without using DataAdapter.Fill 2 times

I am writing a program to manage a office. (Getting rid of Excels XD).
I have a DAL class with the following variables:
private MySqlConnection connection;
private DataSet ds;
private Hashtable adapters;
There is this method:
public bool AddTable(string tableName, string sqlStat)
{
if (!ds.Tables.Contains(tableName))
{
MySqlDataAdapter adapter = new MySqlDataAdapter(sqlStat, connection);
MySqlCommandBuilder builder = new MySqlCommandBuilder(adapter);
adapter.InsertCommand = builder.GetInsertCommand();
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.DeleteCommand = builder.GetDeleteCommand();
adapter.Fill(ds, tableName);
adapters.Add(tableName, adapter);
return true;
}
return false;
}
The program will be connected to a server with MySQL database.
I need to make sure that when one client changes something in the database another client will see the new data, but this is not happening.
You need to read up on optimistic concurrency, which helps solve the problem of multiple users reading and updating the same data at the same time.
I suggest you start here:
http://msdn.microsoft.com/en-us/library/aa0416cz%28v=vs.110%29.aspx
http://www.codeproject.com/Articles/114262/6-ways-of-doing-locking-in-NET-Pessimistic-and-opt

Retrieve/insert data using SQLiteDataAdapter

I'm currently creating a small application using Windows Forms and SQLite. After reading some tutorials I implemented this method for data retrieval:
public DataTable GetDataTable(ref SQLiteDataAdapter adapter, string sql)
{
DataTable dt = new DataTable();
// Connect to database.
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
// Create database adapter using specified query
using (adapter = new SQLiteDataAdapter(sql, connection))
// Create command builder to generate SQL update, insert and delete commands
using (SQLiteCommandBuilder command = new SQLiteCommandBuilder(adapter))
{
// Populate datatable to return, using the database adapter
adapter.Fill(dt);
}
return dt;
}
(As well as another GetDataTable which doesn't take an SQLiteDataAdapter as parameter)
I have three classes, let's call them UI, Link and Database. The UI does nothing but displaying the data and raising events upon user interaction. The Link creates the Database and a SQLiteDataAdapter, retrieves a data table through the method mentioned above, and binds it to a data grid view on the UI. The user cannot alter the table through the data grid view, but should do so through some text boxes. (does this make binding the table to the dgv obosolete?)
What's the best way to get the user input from the text boxes to the database, using the adapter? Or should I use DataReader and some Insert method instead of an adapter?
As of know, the UI exposes its controls through Get-methods. Is there a better solution?
private void Initialize()
{
// Subscribe to userInterface events
userInterface.DataGridViewSelectionChanged += new EventHandler(userInterface_DataGridViewSelectionChanged);
userInterface.NewClicked += new EventHandler(userInterface_NewClicked);
userInterface.SaveClicked += new EventHandler(userInterface_SaveClicked);
// Get dataGridView from userInterface and bind to database
bindingSource = new BindingSource();
bindingSource.DataSource = database.GetDataTable(ref adapter, "SELECT * FROM SomeTable");
userInterface.GetDataGridView().DataSource = bindingSource;
}
void userInterface_DataGridViewSelectionChanged(object sender, EventArgs e)
{
if (userInterface.GetDataGridView().SelectedRows.Count != 0)
{
DataGridViewRow row = userInterface.GetDataGridView().SelectedRows[0];
userInterface.GetIDTextBox().Text = row.Cells["PrimaryKey].Value.ToString();
userInterface.GetOtherIDTextBox().Text = row.Cells["ForeignKey"].Value.ToString();
DataTable dt = database.GetDataTable("SELECT * from SomeTable WHERE ForeignKey=" + row.Cells["ForeignKey"].Value);
userInterface.GetLastNameTextBox().Text = dt.Rows[0]["LastName"].ToString();
userInterface.GetFirstNameTextBox().Text = dt.Rows[0]["FirstName"].ToString();
userInterface.GetCompanyTextBox().Text = dt.Rows[0]["Company"].ToString();
}
}
void userInterface_NewClicked(object sender, EventArgs e)
{
// Get all text boxes and clear them
// Let the UI take care of this by itself?
}
void userInterface_SaveClicked(object sender, EventArgs e)
{
// Get text/data from all text boxes and insert (or update if editing table) into database
// adapter.Update(...)?
}
Cheers!
INSERT, UPDATE and DELETE operations are the working of a DbCommand. You need a different method that takes the sql string and a collection of SQLiteParameter that you use for the INSERT.
I will try to write some pseudocode for the INSERT operation
public class MyHelperClass
{
public static int InsertCommand(string sql, SQLiteParameter[] parameters)
{
int result = 0;
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
using (SQLiteCommand cmd = new SQLiteCommand(sql, connection))
{
cmd.Parameters.AddRange(parameters);
result = cmd.ExecuteNonQuery();
}
return result;
}
}
Now you have to build the parameter array to pass to the help method and this should be done from your UI code
string sqlCommand = "INSERT INTO table1 (FirstName, LastName) VALUES (#fName, #lName)";
SQLiteParameter[] p = new SQLiteParameter[2];
p[0] = new SQLiteParameter("#fName", TextBox1.Text);
p[1] = new SQLiteParameter("#lName", TextBox2.Text);
int rowAdded = MyHelperClass,InsertCommand(sql, p);
The operation for the UPDATE and DELETE command are similar. Also I suggest you to add a version of your GetDataTable that accepts a parameter array instead of building sql commands with string concatenation. As repetead innumerable times here string concatenation leads to errors and, worst of all, to weak code easily exposed to sql injection.

What is the best way to connect to a local database that will be used by two apps?

I'm writting an application in C# that connects to a database that is used by other application. I'm coding the class that access the database like this:
class conexionBD
{
string connString;
protected void miConexion(string ruta)
{
connString = String.Concat("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=", ruta);
}
protected DataTable misEmpleados()
{
string query = "SELECT Fiel1, Field2 FROM Table1";
DataTable dTable = miDatatable(query);
return dTable;
}
protected DataColumn misDptos()
{
DataTable dTable = miDatatable("SELECT OtherField from OtherTable");
return dTable.Columns[0];
}
private DataTable miDatatable(string sqlQuery)
{
OleDbDataAdapter dAdapter = new OleDbDataAdapter(sqlQuery, connString);
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(dAdapter);
DataTable dTable = new DataTable();
dAdapter.Fill(dTable);
return dTable;
}
}
The app firts calls the method "miConexion" to set the path to the database in the hard disc. Then the app connects and disconnects each time I want to get the data stored in "Table1" and "OtherTable".
The database is likely to be accessed and modified by both apps at the same time. "Connecting and disconnecting" is the best way to access the database in this case?
there are 3 improvements you can make:
abstract the specific database adapter to the configuration file.
dispose of ado.net objects when you are finished with them
use transaction when reading and writing to/from the db.
The database is likely to be accessed and modified by both apps at the
same time.
Then you would need to use transactions.
Also check that you open and close connection and the connection remains open for the shortest possible time. OleDb stack is really old if this is a new application consider moving to ORM or at least ADO.NET.
Use an ORM like Entity Framework (EF) or NHibernate to manage the state of the object (if both applications are .Net)
I would recommend NHibernate as you are using OLE data adapter (but see if there are any connectors for the database you are using for EF as it is far easier to setup)..
This is the modification of the method "miDatatable", it connects to an Access Database:
private DataTable miDatatable(string sqlQuery)
{
using (OleDbConnection connDB = new OleDbConnection(connString))
{
OleDbDataAdapter dAdapter;
OleDbCommandBuilder cBuilder;
OleDbCommand command = new OleDbCommand();
DataTable dTable = new DataTable();
OleDbTransaction trans = null;
try
{
connDB.Open();
trans = connDB.BeginTransaction(IsolationLevel.ReadCommitted);
command.Connection = connDB;
command.Transaction = trans;
command.CommandText = sqlQuery;
dAdapter = new OleDbDataAdapter(sqlQuery, connDB);
cBuilder = new OleDbCommandBuilder(dAdapter);
dAdapter.SelectCommand.Transaction = trans;
dAdapter.Fill(dTable);
trans.Commit();
}
catch
{
try
{
trans.Rollback();
}
catch { }
}
return dTable;
}
}

Categories

Resources