问题
I'm creating a new project using MVC5 and plain ADO.NET (just as a learning exercise) and I need to create a repository that registers a model with several related objects that also need to be created at the same time and those objects in turn may need to insert other objects.
The easiest solution I can think of is to have a massive method(in the repository) that receives an instance of the parent object(which contains all the related objects that needs to insert) and also have a single stored procedure that receives all the related data as table-valued parameters and then insert everything using a single transaction.
Though that might seem the most straightforward approach, I'm not a big fan of it, so what I want to know is if there's any way/common practice that I can use to share the same instance of a SqlConnection created for the parent object with the other related objects?
I was thinking that perhaps passing the SqlConnection object in the constructor of the related objects, that way each repository would only have to deal with the logic to insert a single object, but I'm not sure.
Edit
-------------------------------
This is the repository for the parent object (Model), the one that I think, should instantiate the SqlConnection and start the transaction
public class ModelRepository : IModelRepository
{
public int Add(Model entity)
{
using (var conn = new SqlConnection(ConnectionString))
{
conn.Open();
using (var command = conn.CreateCommand())
{
command.Transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted);
command.CommandText = "up_Model_Insert";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(command.CreateParameter("@pName ", entity.Name));
command.Parameters.Add(command.CreateParameter("@pDescription", entity.Description));
//Other parameters...
//Call the repositories of the other objects
//....
//how can I make the other repositories use the same connection and
//transaction as the Model entity?
return Convert.ToInt32(command.ExecuteScalar());
}
}
}
}
The problem is that I don't know how to make the others repositories use the same connection and transaction as the "Model" entity.
I've read the Ninject has this "object scope" concept , but I'm not sure what would be the right one in my case.
回答1:
I'm not sure why you want to 'share' a connection. Back to the basics, you should always encapsulate a connection in a using
block (assume you use EF).
What you are after are transactions, right? What I'm just thinking of my head here right now:
What you could do is wrap your insert logic in TransactionInfo
classes. These TransactionInfo
classes could take an Action
and a repository as parameters. The action eventually does the logic of inserting a single object via the given repository (the repository should follow some interface that provides you with CRUD logic).
When you have multiple TransactionInfo
's, you could send them together somewhere that would do the logic of beginning an database transaction, execute all given Actions
from every TransactionInfo
object and eventually execute the transaction.
TransactionInfo
could have a constructor like:
public TransactionInfo(Action action, ICrudRepository repository)
I hope I've understood you well. Sharing an SqlConnection
seems just wrong to me.
来源:https://stackoverflow.com/questions/39987558/asp-net-mvc-how-can-i-share-the-same-instance-of-a-sqlconnection-through-diffe