Proper abstraction of the database tier in a 3 tier system? - c#

I am creating a 3 tier application. Basically it goes
Client -> (through optional server to
be a thin-client) -> Business Logic ->
Database Layer
And basically making it so that there is never any skipping around. As such, I want for all of the SQL queries and such to be in the Database Layer.
Well, now I'm a bit confused. I made a few static classes to start off the database tier but what should I do for the database connections? Should I just create a new database connection anytime I enter the Database Layer or would that be wasteful? Does Connection.Open() take time whenever you have a ConnectionPool?
To me, it just feels wrong for the Business tier to have to pass in a IdbConnection object to the Database tier. It seems like the Database tier should handle all of that DB-specific code. What do you think? How can I do it the proper way while staying practical?

Because of the ConnectionPool, open a new connection each time you access the db is usually not a problem.
If you can reuse open connection without leaving connections open a long time, and without risking leaving orphaned opened connections, then it doesn't hurt to reuse open connections. (I actually inject a datatool into all my classes that access the db. This is mainly for unit testing purposes, but it also allows me to optionally keep a connection open to be used by multiple calls to the db.)
But again, you should not stress too much about opening/closing a lot of connections. It is more important that your DAL:
is maintainable, simple, flexible
performs as well as possible
(most importantly) always properly disposes of it's connections.

Only open the connection when you need it.
Do not maintain a connection to the database, that is much more wasteful.
Of course your db layer will open the connection, Im not sure why you think the BLL is going to pass a connection to the db. The BLL does not know about the database (at least it shouldnt), it should handle business rules and such. The actual connection is open at the db layer.
Here is a link that shows how the BLL should look:
Validating data in .net
The connection string itself should simply be a private string variable within your db layer class and you should be able to pull connection string information from say a web.config file.

It's okay to create and open a new connection every time you enter the database layer, and close the connection as soon as you're finished with it. .Net/Sql Server handles connection pooling well enough to make this work, and it's the accepted way to do it.
You are also right that you don't pass your connection string in from the business layer. That should be a private (but configurable) member of the data layer.

Traditionally, a separate "Data Access Layer" provides the database context for retrieving and committing data. There are several well-known patterns for this, such as Repository. ADO.NET implements several others, such as Provider.
Entity Framework and LINQ to SQL are also good options to further encapsulate and simplify the isolation of the data tier.

You can create a class (or namespace of classes, depending on the size) to host the database layer. Within your database class, you should just use a connection pool in the database layer. The pool will keep n number of connections open to the database at any given time, so you can just run a query using one of the pooled connections without incurring significant overhead.
With this in place, your database layer should present an "API" of public methods that the business layer can call into. None of these methods should expose a database connection object - those details are internal to the data layer.
Then from your business layer, just call into the database layer's "API" each time you need to run a query.
Does that help?

Related

Change connection string without rebuild

Generally projects are created using the below method:
Create a solution with 1 DAL class (this has a dbml file). Create a 2nd class project called BLL which is the business layer that creates the CRUD operations. Finally have a Asp .Net project.
First thing i do is in the DAL (Data Access Layer) i create a connection to the database and drag the required tables.
I create code to get,edit data etc, in the BLL project.
I then have to add a connection string in the Asp .Net project so it can connect to the database.
The issue i always seem to face is when i deploy the project to a test server i can change the Asp .Net projects web.config connection string easily, but at first run the application breaks (cant connect to the sql database) as in the DAL is still looking at the original connection string. So what i have to do is set the new connection string in the DAL project compile and copy that across which then allows everything to work.
I face the same issue when going from the test server to the live server. I've read about using config files but this is as far as i understand they can be used..... But surely there must be an easier way to,change the connection string in one place without having to recompile my DAL dll?
Are there tricks im missing or addons i could use to take advantage of?
If you dont want to use 2 connection string(one in web.config of your UI and the other one on your Data Access) and you dont want to depend of a specific database(in this case SQL Server), you can use just a single connection string on your web.config UI.
When you done that, on your DA, just use the DLL Microsoft.Practices.Enterprise.Data so you will not depend of SQL for connections.
Next time, when you want to migrate your application, for example, from SQL to Oracle, since you are not using anymore SQLConnection, you just change your connection string and its done!. Your migration to Oracle its done in 1 minute.

Switching between databases in C# winforms

I made an application that generates reports based on data from a database.
The functionality of my application is correct, but I have a following problem: my client has 2 identical databases - one for testing and one for actual work he does.
My application should work with both databases (it should have a "switching mechanism"), but I don't know how to implement it.
I know that I could just switch between connection strings but the problem is that in my reports I use datasets that are bound to one database.
Is it possible to fill those datasets with the data from both databases (since the databases are identical in schema, it should be possible), and how would that be done, or do I have to use duplicate dataset/report pairs?
I'm using C# in VS 2010 with SQL Server 2005, and .rdlc for my reports.
Thanks.
Ideally you should should be able to change the connection string in one place and it should affect project-wide.
This will work ONLY IF you get the connection string from one place. Keep it in the app.config file.
See this article to see how you can store and read the connection string from the app.config file.
You've hit upon the reason why people implement the Repository pattern or at least a version of it.
You really need to remove your business logic away from the database, so that it is database agnostic. It shouldn't care where the data comes from only what it is.
From what you' said the implication is that your client doesn't wants more than just a change in the app.config connection string used for database access.
If that is so then, I know that it will entail some work, your best bet is to have a singleton pattern type class to control all data access to and from your data layer.
Using a known inteface you can use a factory pattern to create access to your development or live database at runtime (perhaps based on an app.config setting or even a test class that has no database access at all, but just returns hard coded test data.

Partially Connected with Multiple Datastores - C#/WPF Solution

I'm building a WPF, C#, .NET solution that needs to rapidly change data connections.
All the connections will eventually sync back to a parent Oracle database, but in the meantime, I might be pulling data from an access database, or a local sql server compact database, or an xml file, or even a web service, or sharepoint. Problem is, I might even need to add providers, and need to be able to keep the providers in sync with each other, and do it real time, with no loss of connection/seamless to the users. This is all dependent on what type of machine, which domain, and what kind of network connectivity we have, and is a client requirement, not something I can change.
Does anyone have a good recommendation for what the best way to accomplish this would be?
Has the client explained why they need this functionality? Often they ask for things to solve a problem that they forsee, without adequate knowledge of how best to solve it.
If you're coding something like an application for a travelling salesman to use, which will have intermittent connectivity to the Oracle database, then maybe you should look at using some means other than a direct database connection for synchronising the databases.
Say using a WCF/SOAP service to pass serialized data objects back and forth or you could look at using MSMQ to transfer changes back and forth between the intermittently connected mobile application and the Oracle database server. It would, of course mean that you'll need to run a server side application/service to handle this data and pass it into the Oracle database, but it would allow for intermittent connections to be handled more easily without having to handle database connection error logic.
In the meantime if your client code should look at layering the code to use a factory Repository type pattern. As business logic just calls an interface it is then possible to use database specific code within your data layer that was decided upon at run time (say through a config setting).
you can create one or two tables in any of your server whcih will include all connection strings and the condtions on which data you need to use which connection .
and your business layer will be independent of connections .
other options is to use sofware facotry pattern.
there you can repository independent of connections and on run time decided which data repository will connect to whcih DB.

Best practice for Window Forms and SQL connection instance

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.

Sharing an Oracle connection across multiple data handlers

I have a solution in which an UpdateController class manages the logic for updating data. This controller calls various classes for managing data (ClaimData, StatementData, etc.). What's the best way to share connection across these data handlers--use a singleton, or create another class for managing the connection and passing it to each data handler? What if the application is multithreaded?
Thanks in advance.
you could use dependency injection to provide each of these with a connection...
another way is to use an Oracle provider with internal Connection pooling (for example Devart dotconnect, I am only a customer)... then you only share the connection string via dependency injection or configuration file... every class instantiates/releases the connection on its own... the central connection pooling takes care of the rest (reusing connections etc)... this way you don't have to worry about any threading issues regarding connections...

Categories