我在调用 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();
}
}
}