0

我在调用 UnitDataProvider 类的 2 个方法的 unitservice 中执行此伪代码。

var units = dataProvider.GetChildrenUnits(parentId);
unit.HierarchyIndex = units.Where( u => u.TemplateId == unit.TemplateId && u.ParentId == null).Max( u => u.HierarchyIndex) + 1;
dataProvider.AddSiblingUnit(unit);

每个方法都会打开一个连接。

如何将其重构为仅使用 1 个连接或重用打开的连接?

或者您认为每个数据提供者方法调用的连接正常吗?

解决方案:数据库上的所有数据访问逻辑都是在 DAL 而不是 BLL 内完成的,因为我认为以下对于我的业务来说没有业务逻辑,它只是数据库逻辑。

public void AddSiblingUnit(Unit unit) 
        {
            if (unit.ParentId == null)
            {
                throw new OnlyOneRootNodeIsAllowedException("Only one Root node is allowed!", null);
            } // Server side check if the root is selected because 2 root units are not allowed

            lock (_lockObject)
            {
                using (var trans = new TransactionScope())
                using (var con = new SqlConnection(_connectionString))
                using (var cmd = new SqlCommand())
                {
                    cmd.Connection = con;
                    con.Open();

                    // SELECT HierarchyIndex for the new inserted sibling
                    string selectCommandText = "SELECT HierarchyIndex FROM UNIT WHERE UnitId = @UnitId"; // UnitId of the selected sibling
                    cmd.CommandText = selectCommandText;
                    cmd.Parameters.AddWithValue("UnitId", unit.UnitId); // the parentId which is the selected UnitId 
                    int hierarchyIndexOfSelectedSibling = Convert.ToInt32(cmd.ExecuteScalar());
                    int hierarchyIndexOfNewSibling = hierarchyIndexOfSelectedSibling + 1;

                    // UPDATE all sibling units whose HierarchyIndex is greater than the HierarchyIndex of the selected sibling
                    string updateCommandText = "UPDATE UNIT SET HierarchyIndex = HierarchyIndex + 1 WHERE HierarchyIndex >= @HierarchyIndex AND ParentId = @ParentId";
                    cmd.CommandText = updateCommandText;
                    cmd.Parameters.AddWithValue("HierarchyIndex", hierarchyIndexOfNewSibling);
                    cmd.Parameters.AddWithValue("ParentId", unit.ParentId);
                    cmd.ExecuteNonQuery();

                    // INSERT new sibling
                    string insertCommandText = "INSERT INTO UNIT (Name,TemplateId,CreatedAt,HierarchyIndex,ParentId) VALUES (@Name,@TemplateId,@CreatedAt,@HierarchyIndex,@ParentId);Select Scope_Identity();";
                    cmd.CommandText = insertCommandText;
                    cmd.Parameters.AddWithValue("Name", unit.Name);
                    cmd.Parameters.AddWithValue("TemplateId", unit.TemplateId);
                    cmd.Parameters.Add("CreatedAt", SqlDbType.DateTime2).Value = unit.CreatedAt;
                    unit.UnitId = Convert.ToInt32(cmd.ExecuteScalar());

                    trans.Complete();
                } 
            }
        }
4

1 回答 1

0

您可以在 dataProvider 类中使用连接池。

这将允许您重用连接,但如果您打算让您的应用程序是多线程的,那么这种方法就会遇到问题。除非你确保你的连接池有一个线程安全的实现,这说起来容易做起来难。

于 2012-11-02T11:50:28.960 回答