asp.net MVC - How can I share the same instance of a SqlConnection through different repository classes

孤街浪徒 提交于 2020-01-04 01:27:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!