Could I store a SqlConnection in the HttpContext?
I mean, how can I share a single SqlConnection across multiple classes?
In my project every class inherits a base abstract class that open and close connection.
This class recognizes if a SqlConnection was opened by another class in that case uses it.
I can store this connection in another way that isn't HttpContext?
There is another method to do this, exp. pass the connection between layers?
THX
I wonder why you need to store a single SqlConnection. It doesn't smell great.
If you really do need to share a single SqlConnection across multiple classes, dependency injection is likely a better option. Have a connection factory instantiate a connection object and pass it around as required.
Otherwise, let the DBMS worry about controlling your connection resources. Create, open and close a connection each time you need one.
You are going wrong way. You shouldn't follow this thinking unless you need to share transaction context as mentioned by Lasse V. Karlsen mentioned in his comment. If you are worried about performance and thi is the reason why you want to keep one connection open and shared then it also wrong. In case of e.g. ADO.NET you have connection pooling. This means that even though you call close on connection it is not closed, it is returned to the pooler. This is a mechanism that keeps track of connections and maximizes efficiency by managing them. If you call Open to get a new connection then under the hood you may get an existing one that was used a few minutes before and that was still kept open by the pooler and returned back for reuse. So, if the motivating force is efficiency, then it is not a path you should follow. It is already taken care of on a lower level. Refer to http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx .
Related
I am currently working on a MVC 4 project and we decided to use plain old SQL and to not rely on EntityFramework.
My question now is what is the best practice to initialize a database connection. I thought about using a Singleton that opens the connection (the connection-string is stored in the Web.config) and then use the established connection throughout the application life-cycle but I'm not sure if this is a good approach!
For database connection, Open as late as possible and close as early as possible.
Instead of having a singleton connection, you should create connection object when ever it is necessary, and better if you use using block, since Connection implements IDisposable and you should get dispose the connection when you are done with it.
ODP.NET supports connection pooling so there is no reason (Unless proven otherwise in your specific case) to keep a Singleton of your OracleConnection object.
The best practice here is imo to use a connection (.NET connection object, not a physical connection) for each statement.
using(OracleConnection connection = ...)
{
...Do work here
}
If you want to know more about a similar approach to what you've just described, look here: https://stackoverflow.com/a/10153406/1289283 . I've already answered that kind of dilemma. Be sure you won't do this on per-application scale, but rather on per-request, otherwise you get into troubles. Per-application is fine for single-user-desktop apps, NOT for webapps! And do not use singleton for this also...
What is best practice for C# Window Forms and SQL connection instance. I need the same SQL connection in all window forms. What is best implementation practice for this? Where do I put the SQL connection?
I am using Compact framework 3.5.
Personally I prefer to leave connection management to the ADO.NET connection pool and everytime I want to query:
using (var conn = new SqlConnection("connection string"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT id FROM foo;";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// ...
}
}
}
When you call conn.Open() a physical connection is not opened, it is drawn from the connection pool, and when the using block end and invokes .Dispose the connection is not closed but returned to the connection pool in order to be reused. This improves performance and relieves me from worrying about where to put or store those SqlConnection instances in applications.
You say you need the same connection in all your forms, but I don't think you should consider that to be axiomatic. You may well need to connect to the same database in all forms, but that's not the same thing - any more than you would need to use the same connection to make multiple requests to a web service.
I would strongly suggest three things:
Use dependency injection to allow a single object to be provided to multiple classes/objects which all need it
Don't inject the actual connection: inject something which can provide a connection, or perhaps just something which can execute a query for you.
Take code which accesses the database out of the user-interface code so you can test each independently of the other.
Generally speaking, database access should be (from the caller's point of view): "open connection, do work, close connection whatever happened" (as per Darin's answer). Let .NET's connection pooling take care of the physical connection to the database. How you structure your code around that will depend on your requirements, and the extent to which they vary between forms. In many cases you may be able to get away with just asking your database access class to execute a query for you with a certain set of parameters and return the results - in other cases you may need more fine-grained control.
As Dimitrov suggested a good approach is to open and close connections only when needed and keep it open the shortest possible time. .NET Connection pool will handle this for you so connections will be reused in a transparent way for you.
In general a good approach is to have another class library to serve as Data Access Layer which wraps the calls to database and does not expose any connection or command usage to the UI, so in the future you would be able to move to another database engine, if needed, changing only the DAL.
Communication from DAL and UI should consist only in objects (entities) or for simple projects DataTables and DataSets. In most of the cases a third project (class library) is in the between and it's called Business Logic, such level manipulates the data from DAL and applies your application specific business logic returning cleaner or elaborated results to the UI.
I have used this approach in many projects already, since about 11 years.
You should make a class with the connection logic in.
If I am using a SqlConnection, apparently the best practice is to dispose of it ASAP, and let the connection pooling handle the details. Should I follow the same pattern when I am using System.Data.Linq.DataContext?
Should I create my context once and pass it along to my methods, or should I get the connection string from my config file and create the contexts multiple times and save on passing the parameters?
Edit: A useful link about identity maps: Architecting LINQ To SQL Applications, part 7
You should keep a data context around only as long as necessary to perform an operation.
The reason for this is that it uses something called an Identity Map so that every time you select say customer 1 you get the same object back. This means it is holding lots of references and will consume more and more memory over time and these results will become increasingly stale.
In the case of a web app it is common to create one per request and the DataContext class is optimised for quick creation.
I am currently working on a C# (.NET) project which connects to a MySQL Community Server database and runs some queries. There are currently 4 classes which use their own MySQLConnection object (I'm using the MySQL .NET connector), in order to connect to the database.
Is this good practice, or should I use one 'global' (static?) connection? Using one single connection is kind of against my habits of structuring the code. Not a big fan of 100000 objects working with one shared static field. I bet it's against most programmers' views too.
I also noticed that once I call connection.Close(), the connection does not necessarily get closed. Trying to .Open() it again would result in an exception. I trust this is because I did not set "Pooling=False" in the connection string. I'll experiment with it. If you have any thoughts on this one too, feel free to drop them here.
So, in short, I'd like some opinions on how to organize my MySQLConnections. If you think a single static MySQLConnection to be used by all of the program's classes is better (not necessarily performance-wise, I'm talking more about the effect of multiple MySQLConnections on the database system itself), let me know why you think so.
I'm expecting for the final program to have around 10 or 15 classes, each actively querying the database.
My rules of thumb are:
keep connections open for as brief a time as possible
let ADO.NET handle connection pooling for you
share connections only when the processes are particpating in a transaction together
So, no you should not use one global static connection. But you could have a utility method that supplies your data fetching methods with an open connection. Then you would do something like (assuming Sql is your utility class):
public IEnumerable<MyClass> GetSomeData()
{
using (var cn = Sql.GetOpenConnection())
{
//get your data here
}
}
You can continue with one connection per class. Most ADO.NET providers use connection pooling per default as you have noticed. Close doesn't really close the connection but return the connection to the pool. However, you should not try to Open() the connection again but create a new connection object.
There is one downfall with using one connection per class and that's transaction handling. Transactions can not be shared over multiple connections (unless you are using TransactionScope).
I usually prefer one connection per "session" and take in the connection in the constructor to my repository classes. (As I usually use inversion of control containers). Google a bit about Unit Of Work implementations.
Do not create a single shared connection. Open as late as possible and close as early as possible. If you need to use a connection for multiple queries, try looking at MARS (multiple active record sets) I don't know if MySQL connector supports that though.
certianly let the system handle connection pooling. db connections are expensive.
public class DALCommon
{
public static string GetConnectionString
{
//return System.Configuration.ConfigurationManager.AppSettings["connectionInfo"];
get
{
NameValueCollection appSettings = ConfigurationManager.AppSettings;
string server = appSettings["server"];
string userid = appSettings["userid"];
string password = appSettings["password"];
return String.Format("server={0};user id={1}; password={2}; database=dbmystock; pooling=false", server, userid, password);
}
}
}
I've got a DB connection string that I'm creating in my web.config:
<connectionStrings>
<add name="DBConn" connectionString="Data Source=<db svr>;Initial Catalog=<dbname>;Integrated Security=True" providerName="System.Data.SqlClient />
</connectionStrings>
or
Data Source=<db svr>;Database=<db name>;User ID=<uname>;Password=<pword>;
but I need this connection to be read only. I've defined all my linq objects with only gets on their properties, and none of my (MVC) repository classes have .SubmitChanges() methods in them so I'm 99% sure the system can't update this DB, but I would also like to set my DB connection to be RO if at all possible. I realise that ideally this should be done at the SQL server end and the user should be made RO, but that (for various reasons, out of my control) can't be done, so I wanted to lock down my connection as the app mustn't write to the DB.
Is there a "readonly" parameter I can apply to the connection string so that it would throw an error or discard the data if any updates were attempted?
Just to reiterate (the 1st answer I had, when asking this, on another forum was "change your DB credentials") I cannot, in any way, change the DB access credentials, these are read-write, and any attempt to change them (currently) crashes the SQL Server database.
This is not my problem, and I can't look at resolving that issue, so that's why I want to look at making the DB connection read-only as it absolutely, positively can't change the DB data.
No, there is no way (that I know of). Unfortunately for you, the right way to do it would be to change the grants of the current user, or create a new user with only select privileges. I realize this is not the answer you are looking for but having a Sql Server that crashes when you try to change things in it seems to be a problem that is really worth looking into. Is it because you are using the "sa" account to connect? If so you should create another user and grant the appropriate permissions to the new user.
What you have under your control is classes to acces code (L2S).
I suggest to override in a partial class the SubmitChanges for your datacontext in order to do nothing ( or even throw an error!) (or implementing all extensibility methods InsertObject, UpdateObject or DeleteObject that belong to your datacontext)
It really depends on what database and DB provider you are using. Some allow readonly access on the connection string, some don't.
For example:
SQL Server 2005 CE, when using the .NET Compact Framework Data Provider for SQL Server Mobile, has a possible File Mode=Read Only; parameter. (see on connectionstrings.com).
SQL Server 2008, doesn't.
You can check more on connectionstrings.com.
there's nothing you can do at the connection string level that prevents writes other than change the user - which you've already said you can't do.
In that case you simply have to do the utmost in your code to prevent any writes; i.e:
any public layers should not expose update/delete/insert semantics or whatever.
make any data layer classes sealed so that they cannot be overriden
However, there's still nothing stopping a programmer from coming along, ripping out your connection string, and sticking it inside their own Connection to perform writes.
You could, therefore, move the connection string somewhere else that only internal code knows how to access (it's still going to be text-file driven, though, don't use a code constant!); it's still not stopping anyone from using it - but it makes it a lot harder.
(added) I should explain why it does not protect it.
Leaving aside that the source of the connection string itself is likely to be accessible, even by protection with encryption libraries etc, there's nothing stopping me reflecting to your code and calling it, apart from trust levels. You might choose to go the whole obfuscation route to prevent me from deconstructing your code; but surely this level of paranoia is not required within your development house?
Ultimately, though, because it's 'SEP' (somebody else's problem) as you put it, and you have no control over that - if anybody asks you why, despite your best efforts, you can't guarantee that no writes will be performed, you can safely blame that 'somebody else'.