Separation of Concerns with EnityFramework - c#

I recently started to get into EntityFramework in order to map my model automatically into a MySql database. So I read some tutorials and started tests to validate them. Everything works fine, as far as I only have one project. If I separate the solution some problems arise. In order to demonstrate this, I set up a console project (lets call it A)with EF6.1 that saves all my data to the database. Everything works fine. If I now create a second console project (lets call it B) and and use the DbContext through a IRepository-Wrapper (from A) some problems occur:
First of all, I have to put my config data for the database and EF config into the App.config of project B. I don't like this, but I can live with this.
Furthermore the application compiles, but throws a exception, as long as I don't reference EntityFramework.SqlServer in project B.
In order to separate the concerns I don't want project B be to know that the data is stored via EF in a database. Or to give a real world example I don't want that my WPF Gui knows, that the data came from a database.
Is there a workaround for these problems? Did I miss something, or do I have to live with that problem when using EF?

For the first problem, you're not forced to put your connection string in the assembly's config file. You can use whatever you like (your own config/ini file, the registry, etc.), and then pass the connection string to the DbContext(connectionString) constructor.
As for the second issue, this seems to depend on how you are abstracting the database. If it is a complete abstraction, then it shouldn't leak any dependencies on EntityFramework.SqlServer. On the other hand, Entity Framework itself already follows the repository design pattern, so I'm not so sure if you need to add another layer on top of it. If you do want to continue with creating a database abstraction layer, consider putting it in a third library project that the other user-facing application projects reference.

Related

Entity Framework - Multiple Database Connections

I have used Entity Framework code first with good results.
The project uses a second, legacy database which is already designed and running.
I'd like to call both databases in the project. Does any one have any suggestions of the best solution to do this?
I have done both seperatly (in tutorials) but never both. Yes its not the best idea to connect to two databases but each database has distinctly different datasets.
I am already using EF Code first and have been using POCO classes. Would you suggest creating a EDMX file as well? Assume would need two db context files?
I have done several solutions where there was a Code First connection and a Database First connection used in the same project without any issues. I would do as you stated, just create the edmx for the existing database.
I generally create one library project for each database and reference them from the main app project, just to help keep things from getting mixed up.
You just instantiate a context for each database and use them just as you would with a single context. They act as completely separate, independent repositories.

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.

What type of c# project should an SSDT model be placed in?

Sorry if this is a totally noob question but I just can't seem to find a starting point on this.
From what I've gathered so far SSDT was developed with the idea that it would be used in a different project that that of the main app for database related coding. I figured that instead of complaining about how much I like the old version back, I'd try things their way and see how well it goes but I can't seem to get a handle on where to begin over here.
Basically I want to use a code first approach and create a database from a designer. If I'm going to create a new project to handle the entity framework, what type of project should it be? a C# class library, WPF.. something else?
I'm not sure if it's of any relavance but the app I'm working on is a WPF app and the database is MySQL.
If you want to use a code-first approach, then that means that the database will be generated by the code. Thus, you will not have a separate database-project, since that would mean that your database is kept in two places. Therefore, your options are:
Use code-first. This usually means a class library (although asp.net mvc usually has the context with entities in the asp.net mvc project, let's call that an exception to the rule). The class library will contain classes with which your database will be generated.
Use a database project, an SSDT project. Your database will be defined here, and when you deploy this project the database will be generated/updated.
Note: AFAIK an SSDT project is specific to SQL Server, so since you are using a MySql database it is not an option.

wcf service testing with fake data

I have been looking for solution for a few days already and could find anything that would help to solve my problem.
I have a WCF service for which I have to make some unit tests. The problem is that service takes data from database in this way:
using (var context = new MyProjectEntities())
{
//here goes the actions
}
MyProjectEntities is autogenerated from edmx model i guess.. (Database first)
So this way it takes all the data from the database and operates on it.
My question is: whats the correct way to feed service with fake data for testing, instead of data from database?
The most trivial way is to use a live database. This isn't too flexible, because you need a new database in a fixed initial state for every single run, and also multiple developers can't use the same database at the same time.
What we do at my company is this: use a single-file database, namely SQL Server CE. If your code is database-engine independent, this can totally work, just change your connection string and you can even put your database to a fixed state by copying a template datafile to the right place. This isn't a really isolated unit test, but it's very simple to implement, it doesn't have the above problems, and you basically get what you need in the end. If your code is database-engine dependent, now you have one more reason to use an ORM solution like NHibernate or Entity Framework.
The best, most flexible, and also most complex solution is using a dependency injection or mocking framework. This is textbook stuff, there's tons of literature on that, it will give you all the flexibility there is.

What's the best way to reuse database access across multiple projects to ensure that when updated it does not break any projects?

I have probably written the same LINQ to SQL statement 4-5 times across multiple projects. I don't even want to have to paste it. We use DBML files combined with Repository classes. I would like to share the same Library across multiple projects, but I also want to easily update it and ensure it doesn't break any of the projects. What is a good way to do this? It is OK if I have to change my approach, I do not need to be married to LINQ to SQL and DBML.
We have both console apps and MVC web apps accessing the database with their own flavor of the DBML, and there have been times when a major DB update has broken them.
Also, since currently each project accesses the DB from itself, which is sometimes on another server, etc. Would it be possible to eliminate the DB layer from being within each project all together? It might help the problem above and be better for security and data integrity if I could manage all the database access through a centralized application that my other applications could use directly rather than calling the database directly.
Any ideas?
The way I handle this is using WCF Data Services. I have my data models and services in one project and host this on IIS. My other projects (whatever they may be) simply add a service reference to the URI and then access data it needs over the wire. My database stuff happens all on the service, my individual projects don't touch the database at all - they don't even know a database exists.
It's working out pretty well but there are a few "gotchas" with WCF. You can even create "WebGet" methods to expose commonly used methods via the service.
Let me know if you want to see some example code :-)

Categories