0

データアクセス層(DAL)を備えたasp.netmvcアプリケーションを実行しています。データベースのCRUDコードの90%を実行した後、ビジネスレイヤーが必要かどうかを自問しました。

しかし、私はそこに何を置くべきですか?DALのすべてのCRUDメソッドは、たとえば1つのSQLテーブルでの単一の選択ではありません。ほとんどの場合、私は多くの結合+SQL集計関数を実行します。言うまでもなく、私はADO.NETを使用していますが、ストアドプロシージャ/トリガーは使用していません。

次に、そのようなメソッドがビジネスレイヤーに属するかどうかをもう一度自問しました。

 /// <summary>
 /// Creates a testplan with all teststeps and their default values for a certain template
 /// </summary>
 /// <param name="testplan"></param>
 /// <returns>true if transaction was successfull else false</returns>
 public void CreateTestplan(Testplan testplan)
 {
            try
            {
                using (var con = new SqlConnection(_connectionString))
                using (var trans = new TransactionScope())
                {
                    con.Open();

                    _testplanDataProvider.AddTestplan(testplan,con);
                    _testplanDataProvider.CreateTeststepsForTestplan(testplan.Id, testplan.TemplateId,con);
                    trans.Complete();                   
                }
            }
            catch (SqlException ex)
            {
                ExceptionManager.HandleException(ex);
            }           
        }

このメソッドは、実際にはDAL内の他の2つのメソッドを呼び出しています。

ここで、AddTestplan + CreateTeststepsForTestplanの両方のメソッドからのすべてのコードを含むTestplanDataProviderクラス内にもCreateTestplanメソッドを配置できるのに、なぜ追加のビジネスレイヤーを導入するのかを自問しました。

どう思いますか?これは良いアプローチですか?

私の意見では、CreateTestplanメソッドにはデータアクセスロジックしか含まれていないので、これを本当に尋ねます。

更新

public void AddTestplan(Testplan testplan, SqlConnection con)
        {

            using (var cmd = new SqlCommand("INSERT INTO TESTPLAN (ReleaseId,TemplateId,CreatedAt,UserId,Name,Duration) VALUES (@ReleaseId,@TemplateId,@CreatedAt,@UserId,@Name,@Duration);Select Scope_Identity();", con))
            {
                var p1 = new SqlParameter("@ReleaseId", testplan.ReleaseId);
                var p2 = new SqlParameter("@TemplateId", testplan.TemplateId);
                var p3 = new SqlParameter("@CreatedAt", testplan.CreatedAt);
                var p4 = new SqlParameter("@UserId", testplan.UserId);
                var p5 = new SqlParameter("@Name", testplan.Name);
                var p6 = new SqlParameter("@Duration", testplan.Duration);

                cmd.Parameters.AddRange(new[] { p1, p2, p3, p4, p5, p6 });
                testplan.Id = Convert.ToInt32(cmd.ExecuteScalar());
            }
        }

 public void CreateTeststepsForTestplan(int testplanId, int templateId, SqlConnection con)
        {
            var teststeps = new List<Teststep>();

            using (var selectCMD = new SqlCommand("SELECT ts.TeststepId, MAX(ts.CreatedAt)FROM Teststep ts INNER JOIN Unit u ON ts.UnitId = u.UnitId Where u.TemplateId = @TemplateId Group by TeststepId", con))
            {
                var p = new SqlParameter("@TemplateId", templateId);
                selectCMD.Parameters.Add(p);

                using (var reader = selectCMD.ExecuteReader())
                {
                    Teststep teststep = null;
                    while (reader.Read())
                    {
                        teststep = new Teststep
                        {
                            Id = Convert.ToInt32(reader["TeststepId"]),
                            CreatedAt = Convert.ToDateTime(reader["CreatedAt"]),
                        };
                        teststeps.Add(teststep);
                    }
                }
            }

            using (var insertCMD = new SqlCommand("INSERT INTO TestplanTeststep (TestplanId,TeststepId,TestState,ErrorText) VALUES (@TestplanId, @TeststepId, @TestState, @ErrorText)", con))
            {
                var p1 = new SqlParameter("@TeststepId", SqlDbType.Int);
                var p2 = new SqlParameter("@CreatedAt", SqlDbType.DateTime);
                var p3 = new SqlParameter("@TestplanId", testplanId);
                var p4 = new SqlParameter("@ErrorText", DBNull.Value);
                var p5 = new SqlParameter("@ErrorScreenshot", DBNull.Value);
                var p6 = new SqlParameter("@TestState", (int)Teststep.TeststepTestState.Untested);

                insertCMD.Parameters.AddRange(new[] { p1, p2, p3, p4, p5 });

                foreach (Teststep step in teststeps)
                {
                    p1.Value = step.Id;
                    p2.Value = step.CreatedAt;
                    insertCMD.ExecuteNonQuery();
                }
            }
    }
4

2 に答える 2

0

データアクセスをBLLから除外する理由は、ビジネスロジックへの変更を最小限に抑えてデータベースまたはデータベースフレームワークを切り替えることができるようにするためです。

たとえば、すべてのADO.NET関連のコードをDALに移動し、後で代わりにEntity Frameworkを使用することにした場合、BLLではなくDALのみが変更されます。

もちろん、ビジネスロジックがほとんどない傾向があり、BLLが作業をDALに渡すだけの場合は、個別のレイヤーを使用しても利益が得られない可能性があります。これは非常に些細なアプリの場合ですが、DALにビジネスロジックが隠されていることを示している場合もあります。

于 2012-07-05T17:43:57.763 に答える
0

一般的に受け入れられているベストプラクティスは、DACをBLから分離することですが、L2SやEntity Frameworkなどを使用している場合は、すでにDALがあり、ビジネスロジックはそれらの部分的な定義に入る可能性があります。クラス。その上に別のDALを追加する必要はありません。私は、ADOをDALを構成する抽象化とさえ考えます。ところで、海峡ADOを使用しているので、Dapperを確認することをお勧めします。最小限の高速DALです。

于 2012-07-05T18:35:54.727 に答える