0

どちらのサービスも、IUnitDataProvider の AddChildrenUnit メソッドを使用します。

CreateTemplate メソッドは AddTemplate および「ルート ユニット ノードの作成」のトランザクションで実行する必要があるため、TemplateService はこのメソッドに既に開いている接続オブジェクトを渡す必要があります。

UnitService は接続オブジェクトを AddChildrenUnit メソッドに渡さないため、コードはコンパイルされません!!!

私の質問は次のとおりです。AddChildrenUnit メソッドを変更して sqlconnection パラメータを削除することはできません。そうしないと、CreateTemplate メソッドの AddChildrenUnit がコンパイルされなくなります。

では、今何ができるでしょうか?私が考えることができる唯一のことは、SqlConnection パラメーターを 1 回使用し、このパラメーターを使用しない 1 つのメソッドを使用して、AddChildrenUnit のオーバーロードされたバージョンです。

面倒だなぁ…

より良い解決策を知っていますか?

テンプレートサービス:

public void CreateTemplate(Template template)
{
    using (var transaction = new TransactionScope()) 
    using (var connection = new SqlConnection(_connectionString))
    {
        connection.Open();

        _templateDataProvider.AddTemplate(template,connection);
        Unit rootUnit = new Unit{ TemplateId = template.TemplateId, ParentId = null, Name = "Root" };
        _unitDataProvider.AddChildrenUnit(rootUnit,connection);

        transaction.Complete();
    }
}

ユニットサービス:

public void AddChildrenUnit(Unit unit)
{
    lock (this)
    {
        IEnumerable<Unit> childrenUnits = _unitDataProvider.GetChildrenUnits(unit.UnitId); // Selected ParentId
        int hierarchyIndexOfSelectedUnitId = childrenUnits.Select(u => u.HierarchyIndex).DefaultIfEmpty(0).Max(c => c);
        int hierarchyIndexOfNewChild = hierarchyIndexOfSelectedUnitId + 1;
        unit.HierarchyIndex = hierarchyIndexOfNewChild;

        _unitDataProvider.AddChildrenUnit(unit);
    }
}

ユニットデータプロバイダー:

/// <summary>
///  INSERT new child at the end of the children which is the highest HierarchyIndex 
/// </summary>
/// <param name="unit"></param>
public void AddChildrenUnit(Unit unit) // 10 ms
{
    using (var trans = new TransactionScope())
    using (var con = new SqlConnection(_connectionString))
    using (var cmd = new SqlCommand("INSERT INTO UNIT (Name,TemplateId,ParentId,CreatedAt,HierarchyIndex) VALUES (@Name,@TemplateId,@ParentId,@CreatedAt,@HierarchyIndex);Select Scope_Identity();",con))
    {
        con.Open();

        // INSERT new child at the end of the children which is the highest HierarchyIndex                
        cmd.Parameters.AddWithValue("HierarchyIndex", unit.HierarchyIndex); 
        cmd.Parameters.AddWithValue("TemplateId", unit.TemplateId);
        cmd.Parameters.AddWithValue("Name", unit.Name);
        cmd.Parameters.Add("CreatedAt", SqlDbType.DateTime2).Value = unit.CreatedAt; 

        unit.UnitId = Convert.ToInt32(cmd.ExecuteScalar());

        trans.Complete();
    }             
}
4

2 に答える 2

0

これはどう?

public void AddChildrenUnit(Unit unit) // 10 ms
{
    AddChilrenUnit(unit, new SqlConnection(_connectionString));
}

public void AddChildrenUnit(Unit unit, SqlConnection connection)
{
    using (var trans = new TransactionScope())
    using (connection))
    using (var cmd = new SqlCommand("INSERT INTO UNIT (Name,TemplateId,ParentId,CreatedAt,HierarchyIndex) VALUES (@Name,@TemplateId,@ParentId,@CreatedAt,@HierarchyIndex);Select Scope_Identity();",con))
    {
        con.Open();

        // INSERT new child at the end of the children which is the highest HierarchyIndex                
        cmd.Parameters.AddWithValue("HierarchyIndex", unit.HierarchyIndex); 
        cmd.Parameters.AddWithValue("TemplateId", unit.TemplateId);
        cmd.Parameters.AddWithValue("Name", unit.Name);
        cmd.Parameters.Add("CreatedAt", SqlDbType.DateTime2).Value = unit.CreatedAt; 

        unit.UnitId = Convert.ToInt32(cmd.ExecuteScalar());

        trans.Complete();
    }             

}
于 2012-11-26T22:06:36.600 に答える
0

これが私がすることです。

public interface IUnitDataProvider
{
    void AddChildrenUnit(Unit unit, string connectionString);
}


public class UnitService:IUnitDataProvider
{
    //Implement AddChildrenUnit the way want
    //pass the connection string but u dont use it
}

public interface UnitDataProvider:IUnitDataProvider
{
    //Implement AddChildrenUnit the way want
}

パブリッククラステンプレートクラス{

private IUnitDataProvider _unitDataProvider;

public templateClass(IUnitDataProvider provider)
{
        _unitDataProvider=provider
}

public void CreateTemplate(Template template)
{
    //pre -addUnit code here

   _unitDataProvider.AddChildrenUnit(unit, connectionstring);

    //Post -addUnit code here

}

}

したがって、使用法に基づいて、正しい具体的な実装を TemplateClass のコンストラクターに渡します (私はそれを TemplateClass と名付けましたが、あなたが何と呼んだかはわかりません)

于 2012-11-26T22:34:35.093 に答える