I am a newbie. Sorry!
My Windows Form App has 3 layer. Presentation has Form_Login with textEdit_Name and textEdit_Pass.
My Connection class:
public class _Connection
{
public OleDbConnection GetConn(string _name, string _pass)
{
OleDbConnection _Conn = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};User ID={1};Password={2};", #"C:\Test\Test.mdb", _name, _pass));
return _Conn;
}
}
My Data Access Layer:
public class getDAL : IDisposable
{
private _Connection getConn = new _Connection();
OleDbConnection _Conn = new OleDbConnection();
public DataTable getDatatable()
{
_Conn = getConn.GetConn();
//Do something
}
}
How can I get _Conn with:
_name = textEdit_Name.Text and _pass = textEdit_Pass.Text
when user login through Form_Login
Perhaps the simplest method would be to set up the ConnectionString details in a static class in your DAL. Something like this:
public static class ConnectionDetails
{
public static string UserName;
public static string Password;
public static string GetAccessConnectionString(string filepath)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};", filepath);
if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(Password))
sb.Append("User Id=admin;Password=;");
else
sb.AppendFormat("User Id={0};Password={1};", UserName, Password);
return sb.ToString();
}
}
Your business layer needs to set the UserName and Password fields of the ConnectionDetails static class whenever they change in your presentation layer, and your DAL classes that need connection strings should get them by calling ConnectionDetails.GetAccessConnectionString with the appropriate file path. Or add FilePath as one of the static fields in that class so that you can set all three from wherever.
If you're intending to use more than one database file then a dictionary of connection data keyed off the file name would probably be a good idea.
You can use the ConnectionStringBuilder Class
public static class BuildConnection()
{
public static GetConnectionString(var userName, var Password)
{
OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();
builder.Driver = "Microsoft Access Driver (*.mdb)";
builder.Add("Dbq", #"C:\Test\Test.mdb");
builder.Add("User Id", userName);
builder.Add("Password", Password);
return builder.ConnectionString; // Here is your connection String
}
}
Here is example how you can pass LoginForm TextBox .Text to Business Layer and Data Access Layer.
Data Access Layer:
class DALClass : IDisposable
{
private _Connection getConn;
OleDbConnection _Conn;
public DALClass()
{
getConn = new _Connection();
}
public DataTable getDatatable(string sUserName, string sUserPass)
{
//pass on user name and password
_Conn = getConn.GetConn(sUserName, sUserPass);
//Do something
return default(DataTable); //return datatable
}
}
public class _Connection
{
public OleDbConnection GetConn(string _name, string _pass)
{
OleDbConnection _Conn = new OleDbConnection(String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};User ID={1};Password={2};", #"C:\Test\Test.mdb", _name, _pass));
return _Conn;
}
}
Business Layer:
class BLClass
{
DALClass _dal;
public BLClass()
{
_dal = new DALClass();
}
public DataTable GetDataTable(string sUserName, string sUserPass)
{
return _dal.getDatatable(sUserName, sUserPass);
}
}
Login Form:
public partial class LoginForm : Form
{
BLClass _bl;
public LoginForm()
{
InitializeComponent();
//object of business layer
_bl = new BLClass();
}
private void button1_Click(object sender, EventArgs e)
{
//pass text boxes values to Business Layer
DataTable dt = _bl.GetDataTable(textEdit_Name.Text, textEdit_Pass.Text);
}
}
Related
I have this class that connects to my oracle database:
public class Conexao : IDisposable
{
private readonly IOptions<Configuracao> _config;
public OracleConnection ConexaoOra{ get; internal set; }
private OracleTransaction _transacao;
private bool _finalized;
private bool _commited;
private const string CONNECTION_STRING = "myConnectionString";
public Conexao(IOptions<Configuracao> config)
{
_config = config;
_finalized = false;
_commited = false;
ConexaoOra = new OracleConnection();
ConexaoOra.ConnectionString = CONNECTION_STRING;
ConexaoOra.Open();
}
~Conexao()
{
Dispose();
}
public void BeginTransaction(System.Data.IsolationLevel level = System.Data.IsolationLevel.ReadCommitted)
{
_transacao = ConexaoOra.BeginTransaction(level);
}
public void Commit()
{
if (_transacao != null)
{
_transacao.Commit();
_transacao = null;
}
_commited = true;
}
}
This class is instantiated every time any transaction is triggered in the DAL class
sample:
using ((conexao == null ? conexao = new Conexao() : conexao))
OracleCommand oracleCommand = new OracleCommand("", conexao.ConexaoOra);
//...
The Json Settings File and the Connection Class are in different projects in the same solution
how to load in this line my connectionString of appSettings Json File?
private const string CONNECTION_STRING = "myConnectionString";
Sorry, I took the example from an old project where I used ServiceStack and it probably had some helpers to ease the procedure. With just plain .NET it seems to be more tedious, so have a look here and here.
i am new with MVC Core, i working on news website Project, how i can display last SQL record on my index?
please describe in details, what should i write in controller and razor page ?
thank you
public class mycontroller:BaseController
{
private readonly IRepo repo;
public mycontroller(IRepo _repo)
{
_repo=repo;
}
[httpGet]
public IActionResult<string> GetLastRecord()
{
return _repo.GetLastRecord();
}
}
public class repo
{
private readonly IDBContextFactory dBContextFactory;
public repo(IDBContextFactory _dbContextFactory)
{
_dbContextFactory=dBContextFactory;
}
public string GetLastRecord()
{
return _dbContextFactory.Select("mydb","select top 1 text from mydb order by autoincreamentedkeyusualyid desc")[0];/* this is bad way of using data table I recommend using this https://stackoverflow.com/questions/33515552/converting-datatable-to-listentity-projectdracula */;
}
}
public interface IRepo
{
public string GetLastRecord();
}
public class DBContextFactory
{
private SqlCommand BuildFactory(string dbName)
{
switch(dbName)
{
case 'mydb':
return CreateMyDB();
}
}
private SqlCommand CreateMyDB()
{
string connectionString = "your connection string";
SqlConnection connection =
new SqlConnection(connectionString));
SqlCommand command = new SqlCommand(connection);
return command.Open();
}
//Private SqlCommand GetMyOpenCommand()
public DataTable Select(string dbName,string query)
{
SqlDataAdapter dataAdapter=new SqlDataAdapter();
dataAdapter.SelectCommand=BuildFactory(dbName);
DataSet dataSet=new DataSet();
dataAdapter.Fill(dataSet);
con.Close();
}
}
public inteface IDBContextFactory
{
SqlCommand BuildFactory(string dbName);
SqlCommand CreateMyDB();
DataTable Select(string dbName,string query)
I have a class library that contains hundreds of static methods and variable as follows…
public class General
{
public static string Con { get; set; }
public static string Func1()
{
using (SqlConnection con = new SqlConnection(Con))
{
// My stuff here
}
}
public static string Func2()
{
using (SqlConnection con = new SqlConnection(Con))
{
// My stuff here
}
}
public static string Funcn()
{
using (SqlConnection con = new SqlConnection(Con))
{
// My stuff here
}
}
}
I referenced this class library to my ASP.Net Webform app and assign connectionstring from Global.asax’s Application_Start event
protected void Application_Start(object sender, EventArgs e)
{
General.Con = ConfigurationManager.ConnectionStrings["Con"].ConnectionString;
}
Everything works fine.
Now that I wanted to change database connectionstring on per-LoggedIn-user basis.
What I have tried:
I stored all user’s connectionstring info at one table in common database and mapped them to respective userIDs.
On Login button click, I could save connectionstring to session.
Session["Con"] = ds.Tables[0].Rows[0][0].ToString();
In class library I used
Public static string Con = System.Web.HttpContext.Current.Session["Con"].ToString();
I get error : Object reference not set to an instance of an object.
If I remove static, all my variable and methods gives an error: An object reference is required for the non-static
If I use new keyword here, error is “Cannot be accessed with an instance reference; qualify it with a type name instead”.
Then I used
public static string Con()
{
string Con = "";
HttpContext httpContext = HttpContext.Current;
if (httpContext.ApplicationInstance.Session.Count > 0)
{
if (httpContext.ApplicationInstance.Session["Con"] != null)
Consd = httpContext.ApplicationInstance.Session["Con"].ToString();
}
return Con;
}
It gives me error: Cannot convert from method group to string
Please help me out…
Your class is static, which means there is a single instance, yet you want to change the connection on a user basis.
That is obviously not going to work. I would personally recommend you allow multiple instances of your class (non-static) and initialize each instance with the connection string as a parameter:
public class General
{
private string _connectionString;
public General(string connectionString)
{
_connectionString = connectionString;
}
}
You can then instantiate it once per session if you want, or simply instantiate it every time you need to use it. I would not recommend adding dependencies into the class (e.g. where the connection string comes to).
var data = new General(ds.Tables[0].Rows[0][0].ToString());
var result = data.Func1();
If for some reason, you need to keep the class static, you would need to either provide the connection string to the function so it can use it, or embed the logic to pull out the connection string from the session into the method:
public static string Func1(string connectionString)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
// My stuff here
}
}
OR
public static string Func1()
{
using (SqlConnection con = new SqlConnection(ds.Tables[0].Rows[0][0].ToString()))
{
// My stuff here
}
}
I would recommend passing the connection string as a parameter if you decide to go this route.
One last option if you wish to keep your class static would be to use a Configurator object that provides the connection string, in order to abstract the location:
public interface IConfigurator
{
string GetConnectionString();
}
public class SessionConfigurator : IConfigurator
{
public string GetConnectionString()
{
var connectionString = Session["Con"].ToString();
return connectionString;
}
}
public static class General
{
public IConfigurator Configurator { get; set; }
public static string Func1()
{
using (SqlConnection con = new SqlConnection(Configurator.GetConnectionString()))
{
// My stuff here
}
}
}
Then upon application startup:
General.Configurator = new SessionConfigurator();
see this below code
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.local);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.remote);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.OrcsWeb);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.Sage);
Unity RegisterType not accepting enum but when if i pass string then no problem occur but i have to use enum. my full code as follow. so some one see my code and tell me what and where to fix in code as a result enum should be accepted.
full code
public enum ConType { local, remote, OrcsWeb, Sage, };
public interface IBBAConnection
{
IDbConnection GetConnection();
string ConType { get; set; }
}
public class BBAConnection : IBBAConnection
{
public ConType ConType { get; set; }
public IDbConnection GetConnection()
{
string _connectionString = "";
IDbConnection connection = null;
try
{
// inside if else logic we fetch connection string from ini file or from any source and inistialize connection.
if (ConType == ConType.local)
{
_connectionString = "put here local db connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
else if (ConType == ConType.remote)
{
_connectionString = "put here remote db connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
else if (ConType == ConType.OrcsWeb)
{
_connectionString = "put here website db connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
else if (ConType == ConType.Sage)
{
_connectionString = "put here sage connection";
connection = new System.Data.SqlClient.SqlConnection(_connectionString);
}
connection.Open();
}
catch (Exception ex)
{
string strErr = ex.Message;
}
return connection;
}
}
public static class Factory
{
static IUnityContainer cont = null;
public static IBBAConnection initialize(ConType oConType)
{
IBBAConnection oDbConnection = null;
cont = new UnityContainer();
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.local);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.remote);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.OrcsWeb);
cont.RegisterType<IBBAConnection, BBAConnection>(ConType.Sage);
oDbConnection = cont.Resolve<IBBAConnection>(oConType);
//oDbConnection.ConType = type;
return oDbConnection;
}
}
looking for guide line that what to change as a result Enum should be accepted.
Below is what I think you should do.
It will dramatically reduce the complexity of BBAConnection because you're letting your IConnectionConfig binding determine the connection string you need.
public interface IConnectionConfig
{
string GetConnectionString();
}
public class LocalConnectionConfig : IConnectionConfig
{
public string GetConnectionString()
{
return "db connection for local";
}
}
public class BBAConnection : IBBAConnection
{
private readonly IConnectionConfig config;
public BBAConnection(IConnectionConfig config)
{
this.config = config;
}
public IDbConnection GetConnection()
{
string _connectionString = "";
IDbConnection connection = null;
try
{
connection = new System.Data.SqlClient.SqlConnection(this.config.GetConnectionString());
connection.Open();
}
catch (Exception ex)
{
string strErr = ex.Message;
}
return connection;
}
}
The registrations:
container.RegisterType<IBBAConnection, BBAConnection>();
container.RegisterType<IConnectionConfig, LocalConnectionConfig>();
Conceptually Speaking
You would normally let your build configurations define what configs you are using. You can then use that in your code to define which config you need.
I have a console application with a base class as following:
public abstract class PaymentSystemBase : IPayable
{
private SqlConnection _connection;
protected PaymentSystemBase()
{
CreateDatabaseConnection();
}
protected void CreateDatabaseConnection()
{
if(_connection == null)
{
string connectionString = ConfigurationManager.AppSettings["connString"];
var connection = new SqlConnection(connectionString);
_connection = connection;
connection.Open();
}
}
public SqlConnection Connection
{
get { return _connection; }
}
public abstract void ProcessPayment();
}
And have a few classes that derive from PaymentSystemBase:
public class PS1 : PaymentSystemBase
{
public override void ProcessPayment()
{
// Work with database using Connection from PaymentSystemBase
}
}
public class PS2 : PaymentSystemBase
{
public override void ProcessPayment()
{
// Work with database using Connection from PaymentSystemBase
}
}
In main program:
var lstPayments = new List<IPayable>
{
new PS1(),
new PS2()
};
var processPayments = new ProcessPayments(lstPayments);
processPayments.Process();
Where:
public class ProcessPayments
{
private List<IPayable> _paymentSystems;
public ProcessPayments(List<IPayable> paymentSystem)
{
_paymentSystems = paymentSystem;
}
public void Process()
{
foreach (var paymentSystem in _paymentSystems)
{
paymentSystem.ProcessPayment();
}
}
}
My question is how to use the same connection from PaymentSystemBase class and close it after processing? As I can see the connection was created again every time when PS1 and PS2 were created.
You shouldn't try to share the connection object. The connection objects themselves are actually quite lightweight, being an abstraction built on top of the actual physical connections, that the ADO.NET connection pool takes care of creating.
So you base class should be something like:
public abstract class PaymentSystemBase : IPayable
{
private static string _connectionString =
ConfigurationManager.ConnectionStrings["connString"].ConnectionString
public static string ConnectionString
{
get { return _connection; }
}
public abstract void ProcessPayment();
}
And then your derived classes should be:
public class PS1 : PaymentSystemBase
{
public override void ProcessPayment()
{
using(var conn = new SqlConnection(PaymentSystemBase.ConnectionString))
{
using(var cmd = new SqlCommand("...",conn)
{
//Prepare command
conn.Open();
cmd.ExecuteXXX();
//Process results, etc
}
}
}
}
You'll notice that I've also switched where the connection string is loaded from via the ConfigurationManager class from AppSettings to ConnectionStrings, which is a dedicated part of the configuration system for storing connection strings. This wasn't actually required but it is more conventional.