My controllers need to get data that is passed back to the view. Where should I open a connection to pass to the repository? Here is an example. This is a part of one of my controllers.
using (var connection = this.GetActiveConnection())
{
var repository = new RefRepository(connection);
var codes = repository.GetPoACodes();
}
Is it bad practice to be opening a connection in the controller? If I don't pass it via the controller, where should I pass the connection to the repository?
Actually Repositories must handle connection themselves, it shouldn't be controller concern.
Controller class must remain thin, and if it gets fat, it would be a code smell.
It would a very good practice if you can use a Dependency Injection Framework (like Ninject, StructureMap, ...) to wire those dependencies , to handle DbContext or Session and SessionFactory (EF or NHibernate), Transaction or namely Unit of Work pattern, Exception Handling and Logging if you want to go thus far.
If you're using Visual Studio then in Project Templates there is an option which create repositories also, you can create a sample project, read the code, and learn how the code is organized.
In this article, under Web API header, you can find out how to do it.
No, you should not open a database connection on your controller.
Controller should talk to your "domain model", which is not the same as your database schema.
In your case, maybe your repository must handle it.
Or even more, if your using Entity Framework or NHibernate, for example, it'd be better let them handle that matter.
Related
This question already has answers here:
How to nest transactions in EF Core 6?
(3 answers)
Closed last year.
I am trying to implement the service and repository patterns in my ASP.NET Core 6 based web application (using EF Core), but I think I am doing a few things wrong. In my controllers I inject a service instance which I can then use like this to get, create, update or delete entities:
[HttpPost]
public async Task<IActionResult> CreateProject([FromBody] Project body)
{
int projectId = await this.projectService.CreateProjectAsync(body);
return CreatedAtAction(nameof(GetProject), new { id = projectId }, null);
}
The CreateProjectAsync function then performs validations (if necessary) and calls the corresponding CreateProjectAsync function of the ProjectRepository class. One important thing to note is that the Project class is created by myself and serves as view model, too. It is mapped to the corresponding EF Core type (such as TblProject) in the repository before it is created/updated in the database or after it has been read from the database.
This approach works fine in many cases but I often encounter problems when I need to use transactions. One example would be that in addition to projects, I also have related entities which I want to create at the same time when creating a new project. I only want this operation to be successful when the project and the related entities were both successfully created, which I cannot do without using transactions. However, my services are not able to create a transaction because they are not aware of the EF Core DbContext class, so my only option right now is to create the transactions directly in the repository. Doing this would force me to create everything in the same repository, but every example I've seen so far suggests to not mix up different entities in a single repository.
How is this usually done in similar projects? Is there anything wrong with my architecture which I should consider changing to make my life easier with this project?
Great question! By default, the EF context is registered as a scoped dependency - so one per request. You could create a simple transaction service (registered as a scoped dependency) that would expose transaction handling. This service could be injected into both your repositories and other service layers as need be.
By returning the transaction object when a transaction is begun, you could grant each layer autonomy over committing or rolling back it's own transaction.
You could also add some cleanup logic to the Dispose method of the transaction service to commit or rollback any open transactions when the service is being disposed.
Edit for personal practice:
I have abandoned the repository pattern for several projects except for frequent get operations. Using the EF context directly in service layers allows me to take advantage of navigation properties to perform complex multi-table inserts or edits. I also get the added benefit of a single round trip to the database to execute these operations, as well as implicit transaction wrapping. Personally, it gets more and more difficult to make the case for the repository pattern on EF projects - other than you get really locked in to EF because it is all over the lower service layers.
I have a multi tenant c# project with 60 microservices connected to multiple postgresql databases. I'm using open/close connection on each transaction. I'm not sure that this is the best practices.
Do I have to open one connection to each database on each microservice and use it on all my activities or open/close on each transaction
You should consider use Unit of Work pattern plus Dependency Injection practices.
I let you here a Microsoft document explaining the Unit of Work pattern
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
If this approach isn´t valid for you, using only ORMs like Dapper or Entity Framework should be another approach, but in this case I strongly recommend you to isolate this in "repositories" entities. This way, everytime you instance and use a repository (using Dependency Injection) you won´t have to deal with transaction details (the connection will be opened every time you instance this entity and closed when you call Dispose method).
I'm using MVC .Net. Usually I always use something like below to create one instance whenever I need to query the DB:
using (EntitiesContext ctx = new EntitiesContext())
{
....
}
Then I see lots of sample codes that always have one instance of DBContext in the controller, use it whenever needed, and Dispose it when the controller is Disposed.
My question is: which one is the right way to use it? Any advantage/disadvantage? Maybe, is there any performance difference?
Thanks
Using a context by controller instance has multiple advantages :
It's scoped to the controller, therefore if you need it multiple times you allocate only one instance
EntityFramework use local caching, then if you query multiple times over the same DbSet with the same parameters, it will match those entities in cache instead of querying the database
If you use the repository pattern, it's a good practice to share your context accross repositories. That way, each repository is able to see what as been done by other repositories if you manipulate multiple repository in the same controller scope
From the Getting Started with ASP.NET 5 and Entity Framework 6 , you can read :
Context should be resolved once per scope to ensure performance and ensure reliable operation of Entity Framework.
See a related SO post that deeply explain why it's better to use this approach.
I am new to ASP.Net MVC and I have written a number of Controller classes that have this ivar:
private ApplicationDbContext db = new ApplicationDbContext();
I have also read that each request creates a new instance of the Controller.
I am concerned about database connection churn.
Should I be using a single global connection object instead? Or is there connection pooling happening behind the scenes and I shouldn't worry about it?
For Entity Framework ORM tool, it is not recommended to use DbContext as a singleton instance, so, avoid to keep it on the global.asax. A good pratice is to use it with the pattern Unit of Work. Read this article.
In this another article you can see sample pros and cons about how to keep an instance of DbContext.
I have a set of many databases that follow the same schema and I've abstracted the pertinent tables in the Model layer of the application. I'm using SQLConnections to handle connecting to the database and Data Adapters and Data Tables to store and move the information back to and through the controllers etc. The code below is what I am currently using, which is working fine for now:
using (SqlConnection con =
new SqlConnection(
"server=MyServersIp\\NameofInstance; " +
"initial catalog=thisisvariable;" +
"user id=username;" +
"password=password123;")) { /* Stuff happening here */ }
What I would like to be using is something more like this here:
using (SqlConnection con =
new SqlConnection(getConnectionString("databaseIdentifier"))
{
/* Stuff still happening here */
}
So I'm looking for the right place to put my method:
public string getConnectionString(string databaseIdentifier)
{
String theConnectionStringIneed = "appropriateConnectionString"
return theConnectionStringIneed;
}
I am very new to MVC and Web API in terms of structure etc, and I want to make sure I'm following best practices.
My question is where in the standard structure should such a method go? I want it to be accessible from wherever in the hopes of keeping the whole Connection String process DRY, but I also need it to be somewhat dynamic (definite output based on database identifier input)
It seems like a simple enough question, but all I can find after some dedicated searching is examples on how to use Entity Framework or folks generating databases from a model, etc, not using Connection strings.
Please advise, and thank you as always SO community.
This is meant to answer your more general question of "My question is where in the standard structure should such a method go? " and just expands on it a little with some architectural thoughts...
Not sure if you're already doing so, though I would put your database tasks - as in all your CRUD and connection stuff - into a project of it's own - Data Access layer in this case.. Keep this project separate from your models. - This kind of directly answers your initial question "where should it go..."
You can then add a reference to your model layer. (assuming you have all your models in a project on their own)
This keeps those 2 separate. Why? Well, one day you might decide to use Entity Framework, or some other means of communicating with your database. If that's the case then you only need to change your data access layer. And you can keep your models looking all shiny and new still.
If you want to really push the boat out then create another project that sits between your web site and the, now new, Data Access layer - call it services. This would be your middleman between your database and your website.
You would call this middleman service from your website controllers. The middleman service then runs off to the data access layer. That layer goes to the database, gets the data, populates the models and gives them back to your middleman. Your middleman now applies any business logic related to your site and also transforms your data models to things like view models (skinny versions of your models just for the website view you're showing) - this has the advantage of not sending big complex objects to your views for rendering. It also keeps business logic (which is more often than not related directly to the project calling the middleman) out of your data access and model layers.
Now things are nicely broken up and you can switch bits and bobs out as your requirements change.
So, in a total laymen term.. The workflow would be something like this:
User clicks a link
Web site controller gets hit to go fetch data...
Controller asks the service middleman for the data, but the
controller only wants a little bit of it, so asks for a small version
(ViewModel)
Service middleman says 'ok, gimme a sec..'
Service middleman then runs over to the data access layer and says
'Gimme this data' and asks for a full blown model (a row from the DB)
The middleman then gets this back from the data access layer and says
'hmm..the controller said he didn't need half of these properties..'
so the middleman creates an instance of a ViewModel (that you
defined, like a model).
The middleman then populates this instance, the view model, with data
from the model the data access layer gave it.
The middleman might also do some other stuff, businessy-logic stuff..
He then hands it back to the controller and says 'there you go
govn'er '
The controller then returns it in its action result.
And there is a fun lil way to explain it :D
A little side note
You mentioned that people generally seem to create a database from models - this is called Code First. You can also do Database First - exactly as it sounds..
I would, for this, recommend Entity Framework Powertools. It has an awesome reverse-engineer tool which will build all of your models & relationships from your DB. Freakin awesome!
If you put your connection strings in the web.config you can use ConfigurationManager.ConnectionStrings:
var connectionString = ConfigurationManager
.ConnectionStrings["ConnectionName"].ConnectionString;
MSDN
I ended up adding a public static method to the WebApiConfig.cs file. This method takes in an identifier and spits back the connection string. There only needs to be the one, so this works alright. I'm moving on from this, but if there are comments for or against this method I'd love to hear it. I'm learning this stuff right now and Web API is a far cry from Web Forms. Thanks to all for your attention!
public static string getConnectionString()
{
return "the connection string";
}
EDIT: After reviewing comments in other answers, I've also added that I'm going to store the better part of the connection string in the web.config and only use the getConnectionString() method to pull from the ConfigurationManager and tack on the initial catalog, the only changing part of the connection string. Thanks all for your attention.
#Darren: I will also definitely look into N-Tier architecture as it looks like a pretty stable way of handling this, although I think it's outside of the scope of my intents as of right now. Thanks all for some excellent information on all sides.