I'm in a hoo-ha with my boss as I can't shift to using newer technologies until I have proof of some outstanding issues. One of the main concerns is how repositories deal with connections. One of the supposedly largest overheads is connecting and disconnecting to/from the database. If I have a repository where I do the following:
public ContractsControlRepository()
: base(ConfigurationManager.ConnectionStrings["AccountsConnectionString"].ToString()) { }
with the class like so:
public class ContractsControlRepository : DataContext, IContractsControlRepository
with functions like:
public IEnumerable<COContractCostCentre> ListContractCostCentres(int contractID)
{
string query = "SELECT C.ContractID, C.CCCode, MAC.CostCentre, C.Percentage FROM tblCC_Contract_CC C JOIN tblMA_CostCentre MAC ON MAC.CCCode = C.CCCode WHERE C.ContractID = {0}";
return this.ExecuteQuery<COContractCostCentre>(query, contractID);
}
Now if in my controller action called _contractsControlRepository.ListContractCostCentres(2) followed immediately by another call to the repository, does it use the same connection? When does the connection open in the controller? When is it closed?
Cheers
EDIT
I'm using hand-written LINQ as suggested by Steve Sanderson in his ASP.NET MVC book.
EDIT EDIT
To clarify, I'm using LINQ as my ORM, but I'm using raw SQL queries (as shown in the extract above) for querying. For example, here's a controller action:
public ActionResult EditBusiness(string id)
{
Business business = _contractsControlRepository.FetchBusinessByID(id);
return View(business);
}
I'm not opening/closing connections.
Here's a larger, more complete extract of my repo:
public class ContractsControlRepository : DataContext, IContractsControlRepository
{
public ContractsControlRepository()
: base(ConfigurationManager.ConnectionStrings["AccountsConnectionString"].ToString()) { }
public IEnumerable<COContractCostCentre> ListContractCostCentres(int contractID)
{
string query = "SELECT C.ContractID, C.CCCode, MAC.CostCentre, C.Percentage FROM tblCC_Contract_CC C JOIN tblMA_CostCentre MAC ON MAC.CCCode = C.CCCode WHERE C.ContractID = {0}";
return this.ExecuteQuery<COContractCostCentre>(query, contractID);
}
Then ContractsControlRepository is instantiated in my controller and used like _contractsControlRepository.ListContractCostCentres(2). Connections aren't opened manually, DataContext deals with that for me.
Without knowing the details of your ORM and how it connects the SQL database drivers will connection pool. When a connection is closed it is released back to the pool and kept open for X number of seconds (where X is configurable). If another connection is opened and all the parameters match (the server name, the application name, the database name, the authentication details etc.) then any free, but open connections in the pool will get reused instead of opening a brand new connection.
Having not read the book in question I don't know what "manual linq" actually is. If it's manual means you're getting the tables back youself then obviously you're doing the connection open/close. Linq to SQL will use a new connection object when a statement is finally executed at which point connection pooling comes into play - which means a new connection object may not be an actual new connection.
Related
I want to create a web API controller that returns product details with id. Using stored procedure calls from a database class, not DB context. Sending Request with ID & getting a response with Jason's values.
I saw many examples but they are directly using stored procedures from the DB context. But I want to introduce a connection string & call that method in business class than a business class call to the controller with the response return.
Please help with a small example
Here is one example. You can choose between using SQL Command or SQL Adapter, try searching a little bit more about it.
Programming isn't only writing a code it's also googling for solutions.
// Setup connection string to access local SQL Server 2000
string connectionString = "server=localhost;" +
"database=Northwind;uid=sa;pwd=manager";
// Instantiate the connection, passing the
// connection string into the constructor
SqlConnection con = new SqlConnection(connectionString);
// Open the connection
con.Open();
// Create and execute the query
SqlCommand cmd = new SqlCommand("SELECT * FROM Customers",con);
SqlDataReader reader = cmd.ExecuteReader();
// Iterate through the DataReader and display row
while(reader.Read()) {
Console.WriteLine("{0} - {1}",
reader.GetString(0), reader.GetString(1));
}
Source
I am trying to build a multilayer application (service) in C#. To be precise, I am trying to build a REST webservice with ASP.NET Web Api which will be hosted on my own (with Owin). Now I got so far that I have the following components(every one of them is in a separate .dll):
- RestHost (which in my case is an console application)
- RestService (here is my web service witch all the controllers)
- InterfacesLayer
- ModelLayer (here are the objects I use, just with their get/set methods)
- DataLayer (every single class inside of ModelLayer has its own class in Datalayer, plus there is the Database connection class)
- BusinessLayer (here all the logic is done, again every class from model has its own class, and this layer communicates with the REST service and the datalayer).
RestHost - as the name says, it is the host of my service. Besides that I am also doing my dependency injection here. Since it is not much code I will post it:
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
// Dependency Resolving
container.RegisterType<IAktData, AktDataImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IAktService, AktServiceImpl>(new HierarchicalLifetimeManager());
container.RegisterType<ILeistungData, LeistungDataImpl>(new HierarchicalLifetimeManager());
container.RegisterType<ILeistungService, LeistungServiceImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IPersonData, PersonDataImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IPersonService, PersonServiceImpl>(new HierarchicalLifetimeManager());
container.RegisterType<IPersistent, FirebirdDB>(new HierarchicalLifetimeManager());
string serverAddress = ConfigurationManager.AppSettings["serverAddress"];
string connectionString = ConfigurationManager.ConnectionStrings["connectionStrings"].ConnectionString;
using (RESTService.StartServer(container, serverAddress,connectionString ))
{
Console.WriteLine("Server started # "+ DateTime.Now.ToString() + " on " + serverAddress + "/api");
Console.ReadLine();
}
}
Oh and what I forgot to mention, but you can see it from the code, in my host application I am also reading the App.Config where my connection string is hosted.
And here is my problem. I am not sure how to access the Database Connection from my service. Here I am implementing Firebird in my data access layer, but I am unsure how to use it in my application. Of course the easiest way would be just to create an instance and pass it to my service but this is the last thing i want to do. I have also been thinking implementing Firebird as a static class or as a singleton, but then i cannot use my IPersistant interface (and besides that, i don't think that this is the right approach).
So my question would be, is there any best practice for this kind of stuff? I somehow need to pass the connectionstring to the implementation of IPersistent (Firebird) but without actually creating an instance of Firebird in my RESTService.
Thanks
The general pattern for a multi-layer application like the one you're building is to have a data layer that provides your services with access to a database, or some other method of persisting data, usually via a repository.
You can then configure your IoC container to inject your connection string into your repository and then inject your repository into your service. This way your service stays agnostic as to how data is persisted and can focus on defining the business logic.
I actually do a similar thing for a repository that instead of persisting data in a database, stores it in a blob on Azure's CDN. The configuration withing my IoC (StructureMap in my case) looks like this:
string storageApiKey = ConfigurationManager.AppSettings["CloudStorageApiKey"];
string storageUsername = ConfigurationManager.AppSettings["CloudStorageUsername"];
this.For<IImageStorageRepository>().Use<ImageStorageRepository>().Ctor<string>("storageApiKey").Is(storageApiKey).Ctor<string>("storageUsername").Is(storageUsername);
With my repository looking like this:
public class ImageStorageRepository : IImageStorageRepository
{
....
public ImageStorageRepository(string storageApiKey, string storageUsername)
{
this.cloudIdentity = new CloudIdentity() { APIKey = storageApiKey, Username = storageUsername };
this.cloudFilesProvider = new CloudFilesProvider(cloudIdentity);
}
....
}
what i want to achieve is:
a central server connected to the database, using entity framework
a server who for some reason can't reach the database but forward the requests to the central server (not all of them only the one who require the database)
some httpclients who can't reach the central server nor the database but only the middle server
I've already tried with success modifying the controller method to create an http client who redo the reuest to the cenral server, but that seems the worst way to me, especially because i've lots of controllers and methods
public User GetUser(int id)
{
if (Properties.Settings.Default.SyncEnabled)
{
System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient();
httpClient.BaseAddress = Properties.Settings.Default.SyncAddress;
var result = httpClient.GetAsync(this.Request.Url.PathAndQuery).Result;
return this.Content(result.Content.ReadAsStringAsync().Result, result.Content.Headers.ContentType.MediaType);
}
else
{
User user = DbContext.Users.Find(id);
user.LastOnline = DateTime.Now;
DbContext.SaveChanges();
return user;
}
}
i was thinking about using register route, but i'd like to know if it's a good idea, before reading how routes works...
i'm also intrested in how would you implement that.
Since nobody gave me an answer i'm gonna suggest myself to try with this:
http://www.iis.net/learn/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing
seems that reverse proxy can do the trick, but i need to do it with two separate iis
In my managed bean i need to access a mySql database.
So far i used code like this:
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/test";
String username = "user";
String password = "1234";
Connection connection = null;
try {
connection = DriverManager.getConnection(url, username, password);
Now i have to do this in more than one bean, so if i need to change the database credentials, i have to fiddle around in like 10 files.
Is there
a way to store the databaseconnection
a way to define some variables for the whole web project
Thanks in advance
First of all you should understand basic architecture of a Java EE project. It is not a good idea connecting databases in managed beans. It is really bad practice. Please have look my previous answer to understand basic architecture.
Database connections is done in Integration Tier and these classes are called Data Access Objects (DAO).
Create a BaseDao class for static connection properties.
class BaseDao
{
private String url = "jdbc:mysql://localhost:3306/test";
private String username = "user";
private String password = "1234";
private Connection connection;
protected Connection getConnection()
{
connection = DriverManager.getConnection(url, username, password);
return connection;
}
}
and extend base class to its derived classes where database connection is needed and access connection by using BaseDao#getConnection().
Furthermore, it is better to keep database connections in a properties file and inject them into proper classes.
Related Tutorial
Read BalusC tutorial for better understanding DAO tutorial - the data layer
It is generally a good idea to store these kind of values in a .properties file. They can then be accessed via java.util.Properties (http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html)
Here is a good tutorial describing how access these files and their values, I suggest you start with this: http://www.mkyong.com/java/java-properties-file-examples/
(More information: http://en.wikipedia.org/wiki/.properties)
In my IDE, I usually create a new source package /src/main/config and put all my configuration-concerning .properties and .xml files in there. If you do it this way, you need to access it like this from within your jsf application:
String configFilePath = "configuration.properties";
props = new Properties();
InputStream propInStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(configFilePath);
props.load(propInStream);
Or you can simply do this:
How to get properties file from /WEB-INF folder in JSF?
I am using Castle ActiveRecord in my Asp.net / MVC 2 / Multi-tenancy application with SQL Server as my backend.
For every user logging in, the app loads the corresponding DB, dynamically at run time like below:
IDictionary<string, string> properties = new Dictionary<string, string>();
properties.Add("connection.driver_class", "NHibernate.Driver.SqlClientDriver");
properties.Add("dialect", "NHibernate.Dialect.MsSql2005Dialect");
properties.Add("connection.provider", "NHibernate.Connection.DriverConnectionProvider");
properties.Add("proxyfactory.factory_class", "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle");
properties.Add("connection.connection_string", strDBConnection);
InPlaceConfigurationSource source = new InPlaceConfigurationSource();
source.Add(typeof(ActiveRecordBase), properties);
ActiveRecordStarter.Initialize(new System.Reflection.Assembly[] { asm1 }, source);
The strDBConnection string comes from another small database that holds the user info, corresponding DB, etc.
Scenario:
When a user logs in, his DB gets loaded, he can do his CRUD jobs -- No Probs !
Another user logs in (from another remote machine) his DB gets loaded -- No Probs !
Now, when the first user reads from DB, he sees new data from the second user's DB
My little understanding for this behavious is : ActiveRecordStarter is a Static object.
Could someone help me with a solution for this situation ?
The expected behaviour:
each user should access his own DB only, securely, in parallel / at the same time.
Thanks a lot !
ActiveRecordStarter.Initialize should only be called once in your app (in Application_Start in Global.asax).
To achieve what you want, create a class that inherits from NHibernate.Connection.DriverConnectionProvider:
public class MyCustomConnectionProvider : DriverConnectionProvider
{
protected override string GetNamedConnectionString(IDictionary<string, string> settings)
{
return string.Empty;
}
public override IDbConnection GetConnection()
{
// Get your connection here, based on the request
// You can use HttpContext.Current to get information about the current request
var conn = Driver.CreateConnection();
conn.ConnectionString = ... // Retrieve the connection string here;
conn.Open();
return conn;
}
}
Then set the connection.provider property to the name of your class:
properties.Add("connection.provider", "MyCompany.Domain.MyCustomConnectionProvider, MyCompany.AssemblyName");