C# Windows forms - Data Conduit to connect to a windows form app - windows-forms-designer

Hi guys I need some help with this dataconduit. Its written by my tutor and we used it on a web development project. I am trying to use it for a windows forms application to connect to the database but i get the following error:
An attempt to attach an auto-named database for file C:\Users.... failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
The data conduit works indeed if i use it on a asp.net website but not on a windows forms
i did try to researched but no luck.
I am just testing it with two text box and a save button
thank you
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data;
///This class uses the ado.net sql classes to provide a connection to an sql server database.
///it is free for use by anybody so long as you give credit to the original author i.e me
///Matthew Dean mjdean#dmu.ac.uk De Montfort University 2011
//you will need to modify the name of the namespace to suit your own program.
namespace MyClassLibrary
{
public class clsDataConduit
{
//connection object used to connect to the database
SqlConnection connectionToDB = new SqlConnection();
//data adapter used to transfer data to and from the database
SqlDataAdapter dataChannel = new SqlDataAdapter();
//ado.net class for building the sql commands
SqlCommandBuilder commandBuilder = new SqlCommandBuilder();
//stores a list of all of the sql parameters
List<SqlParameter> SQLParams = new List<SqlParameter>();
//data table used to store the results of the stored procedure
DataTable queryResults = new DataTable();
//data row used to store the data for a new record
DataRow newRecord;
//string variable used to store the connection string
private string connectionString;
public clsDataConduit()
{
//this is the constructor for the class
//you will need to modify this to suit your own database name and folder structure
//
//variable to store the patth to the database
string DbPath;
//variable to store the partial path and file name of your database
//modify this line to suit your own needs
string DatabaseName = "\\MyDatabase\\NamesData.mdf";
//set the DbPath concatenating the name of your database
DbPath = GetParentPath() + DatabaseName;
//build up the connection string for the sql server database
connectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + DbPath + ";Integrated Security=True;User Instance=True";
}
private string GetParentPath()
///this function returns the path to the parent folder of the solution
{
//get the folder for the project
string DbPath = System.AppDomain.CurrentDomain.BaseDirectory;
//variable to store the position of the \\ characters
int Posn;
//loop through the path twice
for (int Counter = 0; Counter != 2; Counter++)
{
//find the right most instance of \\
Posn = DbPath.LastIndexOf("\\");
//split the path at that point
DbPath = DbPath.Substring(0, Posn);
//do it one more time
}
//return the new path
return DbPath;
}
public void AddParameter(string ParamName, string ParamValue)
///public method allowing the addition of an sql parameter to the list of parameters
///it accepts two parameters the name of the parameter and its value
{
//create a new instance of the sql parameter object
SqlParameter AParam = new SqlParameter(ParamName, ParamValue);
//add the parameter to the list
SQLParams.Add(AParam);
}
public void Execute(string SProcName)
{
///public method used to execute the named stored procedure
///accepts one parameter which is the name of the stored procedure to use
//open the stored procedure
//initialise the connection to the database
connectionToDB = new SqlConnection(connectionString);
//open the database
connectionToDB.Open();
//initialise the command builder for this connection
SqlCommand dataCommand = new SqlCommand(SProcName, connectionToDB);
//add the parameters to the command builder
//loop through each parameter
for (int Counter = 0; Counter < SQLParams.Count; Counter += 1)
{
//add it to the command builder
dataCommand.Parameters.Add(SQLParams[Counter]);
}
//set the command type as stored procedure
dataCommand.CommandType = CommandType.StoredProcedure;
//initialise the data adapter
dataChannel = new SqlDataAdapter(SProcName, connectionToDB);
//set the select command property for the data adapter
dataChannel.SelectCommand = dataCommand;
//use the copmmand builder to generate the sql insert delete etc
commandBuilder = new SqlCommandBuilder(dataChannel);
//fill the data adapter
dataChannel.Fill(queryResults);
//get the structure of a single record
newRecord = queryResults.NewRow();
//close the connection
connectionToDB.Close();
}
public void WriteToDatabase()
//void method that updates changes to the data adapter thus changing the database
{
//update any changes
dataChannel.Update(queryResults);
}
public DataRow NewRecord
///this method provides access to the new record as a single data row
{
get
{
//return the blank data row
return newRecord;
}
}
public void RemoveRecord(int Index)
//void method that removes a record at a specified index in the query results
{
//remove the record
queryResults.Rows[Index].Delete();
}
public void AddToDataTable()
//void method that adds the new record to the table data
{
//add the new record to the table
queryResults.Rows.Add(newRecord);
//re initialise the new record
newRecord = queryResults.NewRow();
}
public int Count
//property that returns the count of records in the query results
{
get
{
//return the count of the query results
return queryResults.Rows.Count;
}
}
public DataTable QueryResults
//public property that provides access to the query results
{
get
{
//return the query results
return queryResults;
}
set
{
//set the query results
queryResults = value;
}
}
}
}
this is the code for my name class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyClassLibrary
{
public class clsName
{
private string firstName;
private string lastName;
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
public void Save()
{
clsDataConduit Names = new clsDataConduit();
Names.Execute("sproc_tblNames_GetAll");
Names.NewRecord["FirstName"] = firstName;
Names.NewRecord["LastName"] = lastName;
Names.AddToDataTable();
Names.WriteToDatabase();
}
}
}

thank you guys but i finally managed to make it work. i am not sure if it is the right way to do it but what u have done is i have commented out the public clsDataConduit() {} method and before this method i have modified the connection string adding the full path of my database as follow: private string connectionString = (#"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users...\NamesData.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");

Related

check db file is exist or not?

I want to create a shared template in which I want to check the SQLite database file is exists or not, and if the file does not exist then create a new DB file in xamarin.
//my function
public Task<CreateDatabase> DbConnection(string DbName, string DbPath)
{
string dbname = DbName.ToLowerInvariant();
string path = Path.Combine(DbPath, dbname);
var database = new CreateDatabase(path);
if (File.Exists(path) == false)
{
var database = new CreateDatabase(path);
}
return null;
}
properties
public class CreateDatabase
{
public string databasePaths { get; }
public CreateDatabase(string databasePath)
{
databasePaths = databasePath;
}
}
You could use Flags to check and create the database if the database doesn't exist.
public static class Constants
{
public const SQLite.SQLiteOpenFlags Flags =
// open the database in read/write mode
SQLite.SQLiteOpenFlags.ReadWrite |
// create the database if it doesn't exist
SQLite.SQLiteOpenFlags.Create |
// enable multi-threaded database access
SQLite.SQLiteOpenFlags.SharedCache;
}
And then set the Flags when you build the connection.
Database = new SQLiteAsyncConnection(Constants.DatabasePath, Constants.Flags);
You could download the sample code form the link below for reference.
https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/todo/

ASP.Net MVC Constructor Injection with Autofac - Change Runtime ConnectionString [duplicate]

I have a specific scenario here where I need to pass the connection string based on the user, because users may be mapped to the different databases based on his/her enterprise.
This is the code I use to resolve the dependency with a static variable:
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IUserRepository>()
.ImplementedBy(typeof(IKS.Dare.Optimix.Repository.EntityFramework.UserModule.UserRepository))
.DependsOn(Dependency.OnValue("connectionString", DatabaseSettings.DefaultConnectionString))
);
}
Because this DefaultConnectionString is supposed to be a dynamic one, I don't want to lock this variable to make it thread safe, as this would degrade the performance. I would want a way so that I can deal with such situation.
Possible consideration which can be that we can give a session, which can be applied as follows:
DynamicParameters((k, d) => d["connectionString"] = Session["connectionString"])
But this is in a different project which doesn't utilize any web component, it's just an installer project which is basically designed for resolving the dependencies only.
My Generic repository looks like following
public class GenericRepository<T> : IGenericRepository<T> where T : BaseEntity
{
private const string IsActive = "IsActive", DbContext = "dbContext", EntityPropertyName = "Entity";
private string connectionString = String.Empty, provider = String.Empty;
public GenericRepository(string connectionString, string provider)
{
this.connectionString = connectionString;
this.provider = provider;
}
public int Count()
{
string tableName = typeof(T).Name;
string query = SqlQueryConstants.SelectCount + SqlQueryConstants.Space + tableName;
int count = DbHelper.ExecuteScalar<int>(query: query, commandType: System.Data.CommandType.Text, connectionString: connectionString, provider: provider, parameters: null);
return count;
}
}
DBHelper class looks like follows
public static int ExecuteNonQuery(string query, CommandType commandType = CommandType.StoredProcedure,
IList<DbParameter> parameters = null, int? timeout = null, string connectionString = "", string provider = "")
{
using (var connection = CreateDbConnection(connectionString, provider))
{
connection.Open();
using (DbCommand command = CreateDbCommand(sqlQuery: query, parameters: parameters,
connection: connection, commandType: commandType, timeout: timeout))
{
return command.ExecuteNonQuery();
}
}
}
public static DbParameter CreateParameter<TValue>(string name, TValue value, DbType dbType,
ParameterDirection parameterDirection = ParameterDirection.Input, string provider = "")
{
DbParameter param = CreateDbProviderFactory(provider).CreateParameter();
param.Value = value;
param.ParameterName = name;
param.DbType = dbType;
param.Direction = parameterDirection;
return param;
}
public static DbConnection CreateDbConnection()
{
return CreateDbConnection(String.Empty, String.Empty);
}
public static DbConnection CreateDbConnection(string connectionString = "", string provider = "")
{
DbConnection connection = null;
if (String.IsNullOrEmpty(provider))
{
if (String.IsNullOrEmpty(DatabaseSettings.DefaultProvider))
throw new ArgumentNullException("provider");
else
provider = DatabaseSettings.DefaultProvider;
}
connection = CreateDbProviderFactory(provider).CreateConnection();
connection.ConnectionString = connectionString;
return connection;
}
Any help would be greatly appreciated.
Note : I couldn't edit steven's answer.
[EDIT] To make it more clear it can be implemented as:
Here controller is inherited from BaseController
public class UserController : BaseController
{
//
// GET: /Index/
private IUserRepository userRepository;
public UserController(IUserRepository userRepository)
: base(userRepository)
{
this.userRepository = userRepository;
}
}
and BaseController is inherited from Controller where in the database settings are being set in the constructor of Base controller so that we don't need to set it everywhere
public abstract class BaseController : Controller
{
public BaseController(IUserRepository userRepository)
{
userRepository.connectionStringProvider.Provider = WebUtilities.CurrentUserData.Provider;
userRepository.connectionStringProvider.ConnectionString = WebUtilities.CurrentUserData.ConnectionString;
}
}
Since, the connection string is runtime data, you should not use it to construct your application components, as is described in this article. So as the article advices, you should hide the connection string behind a provider abstraction. For instance:
public interface IConnectionStringProvider {
string ConnectionString { get; }
}
This way your repositories can depend on IConnectionStringProvider and can call IConnectionStringProvider.ConnectionString at runtime:
public int Count()
{
string tableName = typeof(T).Name;
string query = SqlQueryConstants.SelectCount + SqlQueryConstants.Space + tableName;
return DbHelper.ExecuteScalar<int>(
this.connectionStringProvider.ConnectionString,
provider: provider, parameters: null);
}
It will be trivial to create an IConnectionStringProvider to will get the correct connection string for you:
class DatabaseConnectionStringProvider : IConnectionStringProvider
{
public string ConnectionString => Session["connectionString"];
}
Since this clas depends on application-specifics (the ASP.NET session in this case), the class should not be part of the application's core logic. Instead, this adapter should live in the application's start up path (a.k.a. the composition root, the place where you configure your container).
You might even want to consider not passing along the IConnectionStringProvider into your repositories, but instead create an abstraction that will create a connection itself. This will hide the fact that there is a connection string completely.
What you're looking for is multi tenancy. You can google "castle windsor multi tenancy" and find a number of useful articles.
Here's a similar Stackoverflow question that links to some good articles on Windsor and multi tenancy. In particular, look into Windsor's IHandlerSelector interface.

How to invoke webservice from sql server 2008?

I am working on asp.net(4.0) web application for database i have SQL SERVER 2008. I have created one Web Service, its functionality is to insert data into database. I have deployed my Web Service on the local IIS, in browser its working fine mean it is inserting data in database but my task is to create a procedure that will pass parameters to the Web Service and then Web Service will insert that data. I have tried many thing for this but could complete this task. Any idea that how i can invoke Web Service from SQL SERVER.
I have tried many things like below link and similar techniques that are mention on this URL
http://www.sqlservergeeks.com/forums/microsoft-data-platform/sql-server-bi/9/sql-programming-calling-the-web-service-thru-sql
I have also tried end point but couldn't complete. Even HelloWork method is not getting called from SQL SERVER.
Web Service Name WebService1.asmx
Method public string SaveRecord(string a, string b, string c, string d)
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public string SaveRecord(string userid, string fname, string lname, string email)
{
//here is my code to save records is database
return "";
}
It is possible to call web service from sql server through integration with SQLCLR. Below is code snippet of CLR trigger which received data about deleted records from DB and send it to remote through web service call.
[SqlTrigger(Name = "OnDelete", Target = "Contact1", Event = "FOR DELETE")]
public static void OnDelete()
{
string recid, accountno, address3;
recid = accountno = address3 = string.Empty;
var sqlContext = SqlContext.TriggerContext;
using (var connection = new SqlConnection("context connection=true"))
{
var command = new SqlCommand("SELECT recid, accountno, address3 FROM DELETED; ", connection);
connection.Open();
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
recid = reader[0].ToString();
accountno = reader[1].ToString();
address3 = reader[2].ToString();
}
}
}
if (!string.IsNullOrEmpty(address3))
{
var token = new CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = "organization";
using (var crmService = new CrmService())
{
crmService.Url = "http://domain:5555/MSCRMServices/2007/CrmService.asmx";
crmService.Credentials = new System.Net.NetworkCredential("username", "password", "domain");
crmService.CrmAuthenticationTokenValue = token;
crmService.UnsafeAuthenticatedConnectionSharing = true;
crmService.PreAuthenticate = true;
crmService.Delete(EntityName.contact.ToString(), new Guid(address3));
}
}
}

Backup of the database in entity framework

i working with entity famework i need to transfer that code
RESTORE DATABASE [showing8-5-2013] FROM DISK = N'C:\Program Files (x86)\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\Backup\Company.bak' WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 10
to code Entity frame work
any help thanks
EF is a DB neutral provider concept. Such commands are by their nature DB specific. EF exposes a way to execute an SQL command:
MyContext.Database.ExecuteSqlCommand();
But you may as well just do it directly.
Pass your SQL command into a custom routine eg:
private static bool ExecuteSqlStatement(string connectionString, string statement) {
int rowsAffected;
using (var sqlConnection = new SqlConnection(connectionString)) {
using (var sqlCommand = new SqlCommand(statement, sqlConnection)) {
try {
sqlConnection.Open();
rowsAffected = sqlCommand.ExecuteNonQuery();
}
catch (Exception ex) {
// your handler or re-throw....
return false;
}
}
}
return rowsAffected == -1;
// see http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx
}

Storing connection in a static class (ASP.NET)

Since I'm using Postgresql and can't use LINQ to SQL, I wrote my own wrapper classes.
This is a part of the Student class:
public class Student : User
{
private static NpgsqlConnection connection = null;
private const string TABLE_NAME = "students";
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
/// <summary>
/// Reads data from the data reader and moves it to the Student class.
/// </summary>
private static void ReadFields(Student student, NpgsqlDataReader dr)
{
student.Id = Int32.Parse(dr["id"].ToString());
student.FirstName = dr["first_name"].ToString();
student.LastName = dr["last_name"].ToString();
student.Password = dr["password"].ToString();
}
/// <summary>
/// Updates the student
/// </summary>
public void Update()
{
Connect();
Run(String.Format("UPDATE " + TABLE_NAME + " SET first_name='{0}', last_name='{1}', password='{2}' WHERE id={3}", FirstName, LastName, Password, Id));
connection.Dispose();
}
/// <summary>
/// Inserts a new student
/// </summary>
public void Insert()
{
Connect();
Run(String.Format("INSERT INTO " + TABLE_NAME + " (first_name, last_name, password) VALUES ('{0}', '{1}', '{2}')",FirstName, LastName, Password));
connection.Dispose();
}
private static void Run(string queryString)
{
NpgsqlCommand cmd = new NpgsqlCommand(queryString, connection);
cmd.ExecuteScalar();
cmd.Dispose();
}
private static void Connect()
{
connection = new NpgsqlConnection(String.Format("Server=localhost;Database=db;Uid=uid;Password=pass;pooling=false"));
connection.Open();
}
//....
So as you see with every INSERT, DELETE, UPDATE request I'm using Connect() method which connects to the database. I didn't realize how stupid it was before I had to wait for 10 minutes to have 500 rows inserted, as there were 500 connections to the database.
So I decided to move Connection property to a static DB class.
public static class DB
{
private static NpgsqlConnection connection = null;
public static NpgsqlConnection Connection
{
get
{
if (connection == null)
{
connection = new NpgsqlConnection(String.Format("Server=localhost;Database=db;Uid=uid;Password=pass;pooling=false"));
connection.Open();
}
return connection;
}
}
public static void Run(string queryString)
{
NpgsqlCommand cmd = new NpgsqlCommand(queryString, connection);
cmd.ExecuteScalar();
cmd.Dispose();
}
}
It works now! I replaces all Run methods in the Student class with DB.Run
But I want to know if it will work fine with a lot of people online, not me only. I'm not sure how static things work with ASP.NET, maybe it'll eat a lot of memory?..
It is better not to store the connection in a static field. Create the connection object on demand and let the connection pooling manage your connections.
You can enable connection pooling for PostgreSQL and let the pooler manage connections for you. Then you can use either piece of code without worry. Even when you issue multiple open/close commands the pooler will optimize them.
This provides you more flexibility and less worry about a custom management solution, also less code and edge cases. It will depend on the database provider you're using. Something in the connection string like:
Pooling: True or False. Controls
whether connection pooling is used.
Default = True
If you need a database provider that uses connection pooling for Postgres one option is npgsql: Npgsql is a .Net data provider for Postgresql.
It supports connection pooling as described in the docs.
Static classes are singletons. The danger here is what they reference. Because they always stay alive, everything they keep a reference to will not be garbage collected.
To see if this is the case, profile your web servers memory. If it always grows and never shrinks, you may be constantly adding references in a static class which never get collected.
In all honesty though, I'd create it only as needed, and completely avoid all of this.
EDIT:
I mean don't worry about sharing one single connection object across your data access layer. If the provider you're using supports connection pooling, then it will handle the actual connections made to the database. Just use and dispose of your connection objects as needed at any point in your data access layer.
using (var connection = new NpgsqlConnection("your connection string"))
{
//your data access stuff.
}
I know code like this is rather big, bulky, and repetitive, but that's ADO.NET. As long as you isolate these calls in their own classes by creating a data access library/layer, it's very manageable. Hiding the ADO.NET objects in a static class is dangerous, because you'll inevitably forget to close a connection or call Dispose() somewhere. Plus you run the risk of building a large object graph that will never get garbage collected.
public class Dataconnect
{
public static string connstring = ConfigurationSettings.AppSettings["SQLConnection"].ToString();
SqlConnection objcon = new SqlConnection(connstring);
SqlCommand objcmd = new SqlCommand();
public bool Opencon()
{
try {
if (objcon.State == ConnectionState.Closed)
{
objcon.Open();
}
objcmd.Connection = objcon;
return true;
}
catch (Exception ex) { throw new Exception("Error: In Open connesction"); return false; }
}
public bool Closecon()
{
try
{
if (objcon.State == ConnectionState.Open)
{
objcon.Close();
}
objcmd.Dispose();
return true;
}
catch (Exception ex) { throw new Exception("Error: In Close connesction"); return false; }
}
public static int ExecuteQuery(SqlCommand sqlcmd)
{
try
{
Dataconnect objdc = new Dataconnect();
int affectedrecord = 0;
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
affectedrecord = sqlcmd.ExecuteNonQuery();
objdc.Closecon();
objdc = null;
return affectedrecord;
}
else { return affectedrecord; }
}
catch (Exception ex) { throw ex;/* new Exception("Error: In ExecuteNonquery");*/ }
}
public static DataTable Generatedatatable(SqlCommand sqlcmd)
{
try { Dataconnect objdc = new Dataconnect();
if (objdc.Opencon() == true)
{
sqlcmd.Connection = objdc.objcon;
SqlDataReader dr;
DataTable objdt = new DataTable();
dr = sqlcmd.ExecuteReader();
objdt.Load(dr);
objdc.Closecon();
objdc = null;
return objdt;
}
else { return null; }
}
catch (Exception Exception) { throw Exception /*new Exception("Error: In Generatedatatable")*/; }
}

Resources