0

できる限り簡潔にしようと思います。とてもシンプルなはずなので、我慢してください。

  • 目標:

    プロジェクトの特定のセクションを普遍化しようとしSQL databse transactionsています。

サイドノート

あなたの答えを助けるために、私は以下を貼り付けました(参考のために)

使用法コード:をGetTestOfTablTime()返しますDataTable

クラス:SQLDBInteractionこれは別のクラスです-final(SQLトランザクション)ステージを担当します

以下のこのコードでは、私が呼ぶものを構築しています:「ストアドプロシージャのメタデータ

そのクラスは、すべてのSQLDbSPを保持するクラスです。

HTSPs(HTは会社のエイリアスです)

このクラスは、それぞれSP (必要な)を保持しています parameter

HTSPsクラスには別のサブクラスが含まれ、すべての名前に対して、各名前に対してSPのみが含まれます。const stringSP

public sealed class HTSPs
{

//so for example this is one of the members of this class - a stored procedure
//its mission: get evnents with specified id OF specified userId in spec' month, year..

    public sealed class GetTimesWithCustomerNames
    {
        //if I DO need Constructor for its parameters how do I properly format the constructor?
        public GetTimesWithCustomerNames()
        {
            Userid.ParameterName = ParNameUserid;
            Month.ParameterName = ParNameMonth;
            Year.ParameterName = ParNameYear;
            EventId.ParameterName = ParNameReasonid;

        }

        const string ParNameUserId = "@userId",
                     ParNameMonth = "@month",
                     ParNameYear = "@year",
                     ParNameEventId = "@eventId";

        public static SqlParameter Userid = new SqlParameter();
        public static SqlParameter Month = new SqlParameter();
        public static SqlParameter Year = new SqlParameter();
        public static SqlParameter EventId = new SqlParameter();            
    }
}

したがって、問題は次 のとおりです。請負業者を初期化するにはどうすればよいですか?

StoredProcedureシンプルなカスタマイズされた「メタデータ」を作成する適切な方法は何ですか

Iv'eは現在、以下のメソッドの実装を完了しています(その問題は別として...)

利用方法

これは、 /DataTableを使用しているときに戻るメソッドです。HTSPs classconstuctor

using SPTime = HT_DBSchema.HTSPs.GetTimesWithCustomerNames;

private DataTable GetTestOfTablTime()
{
    SQLDBInteraction.DataContainer DC_Time = new SQLDBInteraction.DataContainer();

    SQLDBInteraction.SqlParamList parmsTime = new SQLDBInteraction.SqlParamList();
    Dictionary<SqlParameter, int> SqlCmdParDict = new Dictionary<SqlParameter, int>();
    parmsTime.SqlCmd.CommandType = CommandType.StoredProcedure;
    parmsTime.SqlCmd.CommandText = AppDb.MetaSqlSProc.Time.Name;
    parmsTime.SP_Name = AppDb.MetaSqlSProc.Time.Name;
    parmsTime.TableName = AppDb.MetaSqlTable.Time.Name;

    //While folowing implementation Does Work I comented it out to try using the SP Struct
    //ParmsTTime.SP_Params.Add(new SqlParameter(SPTime.ParNameMonth, 9));
    //ParmsTTime.SP_Params.Add(new SqlParameter(SPTime.ParNameReasonid, 1));
    //ParmsTTime.SP_Params.Add(new SqlParameter(SPTime.ParNameYear, 2012));
    //ParmsTTime.SP_Params.Add(new SqlParameter(SPTime.ParNameUserid, 3571));


    //here's where I'm currently stuck, in section below. trying to assign values for the SqlCommand
    parmsTime.SqlCmd.Parameters.AddWithValue(SPTime.ParNameMonth, 9);
    parmsTime.SqlCmd.Parameters.AddWithValue(SPTime.ParNameYear, 2012);
    parmsTime.SqlCmd.Parameters.AddWithValue(SPTime.ParNameReasonid, 1);
    SPTime.Userid.Direction = ParameterDirection.Input;
    SPTime.Userid.SqlValue = 3571;
    return DC_Time.LocalTbl_V3(ParmsTime);
 }

アップデート

上記のコードの最後の行は、パラメーターの割り当てを実装しようとしています。

したがって、以下を使用する必要はなくなります。

SQLDBInteraction.SqlParamList.SP_Params(これはList<SqlParameter>

代わりに私は本当に使用できるようにしたいと思います

SQLDBInteraction.SqlParamList.SqlCmd.Parameters

これは、データベースと対話するために必要なほとんどの手順ですでに使用されているため、

だからこれは私が余分な変数のいくつかの不必要な使用法を落とす方法です

同時に、私はSqlCmd(parmsTime.SqlCmd.Parameters.Add(......))を割り当てたいと思いました

構造体を使用-RealSPTime SqlParameters

...現在の名前を表す文字列を使用する代わりに

parameter.name-(SPTime.ParNameMonth, someValue

最終段階-SQLトランザクション

トランザクションを実行するSQLDBInteractionクラス

public class SQLDBInteraction
{
    public class SqlParamList
    {
        public SqlCommand SqlCmd = new SqlCommand();
        public List<SqlParameter> SP_Params = new List<SqlParameter>();
        public String SP_Name;
        public string TableName;
        public string SelectCommand;
        ///public SqlCommandType SelectedCmdType;
    }

    public class DataContainer
    {
        public DataTable LocalTbl_V3(SqlParamList Params)
        {
            SqlConnection sqlConnection;
            DataTable Usrs = new DataTable(Params.TableName);
            SqlDataAdapter sqlDataAdapter;

            using (sqlConnection = new SqlConnection(WebConfigurationManager.ConnectionStrings["HTConn"].ConnectionString))
            {
                sqlConnection.Open();

                using (Params.SqlCmd.Connection = sqlConnection)
                {
                    using (sqlDataAdapter = new SqlDataAdapter(Params.SqlCmd.CommandText, sqlConnection))
                    {
                        if (sqlDataAdapter.SelectCommand.Parameters.Count > 0 == false)
                        {
                            sqlDataAdapter.SelectCommand = Params.SqlCmd;
                            sqlDataAdapter.Fill(Usrs);
                        }
                    }
                }
            }
            return Usrs;
        }

ストアドプロシージャのパラメータの割り当てられた部分で私が間違っていることを誰かが見つけたら、本当に感謝します。SQL Command

4

1 に答える 1

0

ついに...これが「問題」に対する私自身の答えです。

微調整する機会はいつでもあるので...さらに磨きをかけます。

私は解決策を実装する方法を見つけましたが。

手始めに:

概要

次のように、3 段階のプロセス - データ抽出を接続します。

第 1 段階 : テーブルの名前と ID、および構造体内のストアド プロシージャの割り当て

第 2 段階: SQL パラメータ コレクションの構築 /List <SqlParameter> 最終的な SQL コマンド用。

第 3 段階: これらstructの sを使用して sql コマンドをフォーマット/構築することにより、

引き換えに、ストアドプロシージャのSQL命令を介して、要求に応じて取得しSystem.Data DataTableます...当然です。

背景の準備 - コードの再利用のために

これらの最初の 2 つのコード ブロックは、2 つの別個のファイルに格納されます。

最初のファイルは、SQL データベース スキーマを保持するためのものです。

テーブル名 、テーブル (カスタム) ID 、列名 、およびストアド プロシージャ名とパラメーター。

public sealed class HTDB_Tables
{
    // this is the class that will hold all Sql server - tables Names

    public const string TblTime = "tblTime";
}

 // the class for Stored Procedures Paramaters - (for each stored procedure)
public sealed class HTDB_SPs
{
    // for example this is one of the stored procedures
    public sealed class GetTimesWithCustomerNames
    {

        public static List<SqlParameter> SqlParlst(string SlctdUserID, string SlctdMonth, string SlctdYear, string SlctdEventID)
        {
            SqlParameter Userid = new SqlParameter( UserIdParName, SlctdUserID);
            SqlParameter Month = new SqlParameter(MonthParName, SlctdMonth);
            SqlParameter Year = new SqlParameter(YearParName, SlctdYear);
            SqlParameter EventId = new SqlParameter(EventIdarName, SlctdEventId);

            List<SqlParameter> RetSqlParLst  = new List<SqlParameter>();
            retSqlParLst.Add(UserId);
            retSqlParLst.Add(Month);
            retSqlParLst.Add(Year);
            retSqlParLst.Add(EventId);

            return retSqlParLst;
        }



        const string UserIdParName = "@userId",
                     MonthParName = "@month",
                     YearParName = "@year",
                     EventIParName = "@eventId";
  
    }
}

// a numeric value that's used to reference the table
// the id is passed as a parameter to a javascript-Jquery Update function 
// through the textbox control - "textchange event" - attribute,
// as reference to which table to send the updated data .

// then it is proccessed  in code behind  as table id  inside the application 
// via a switch on the parameter sent by Jquery-ajax function


public sealed class HTDB_tblIDs
{
    public const int tblTime = 1;

   //this is only an example , for one of tables 
   //as it requierd that all sql database tables(that i want to work with this project)
   // will be added here too
   // this could be done via using code smith or through few simple 
  // steps you could do it via C# method that will list all your 
  // database tables names etc'
}

2 番目のファイルnameapaceは、すべての Helper クラスを格納する一般的な使用法 Helperです。

クラスの 1 つ (次のコード ブロック) は、structsを保持するクラスです。

1 つはテーブル用、もう 1 つはストアド プロシージャ用です。

これら 2 つは、後でアプリケーションのcode behind.

            public class DBMetaDetails
            {
                public struct DbTable
                {
                    public DbTable(string tableName, int tableId): this()
                    {
                        this.Name = tableName;
                        this.ID = tableId;
                    }
                    public string HtmlOutput;
                    public string Name { get; private set; }
                    public int ID { get; private  set; }
                }

                public struct SProc
                {
                    public SProc(string SProcName, int SprocID, List<SqlParameter> CurrSpParList)
                        : this()
                    {
                        this.Name = SProcName;
                        this.ID = SprocID;
                        this.SpParList = CurrSpParList;
                    }
                    public string Name { get; private set; }
                    public int ID { get; private set; }
                    public List<SqlParameter> SpParList { get; private set; }
                }
            }

したがって、上記のコードは両方とも2つの別々のファイルにあります...

上記のコードは、作成する必要があるすべてのアプリケーションで使用できることを意味します。

したがって、この最初のバックグラウンド作業が完了した後の実装は非常に簡単です。

  • 第二部

現在のプロジェクトでの実装。

次のコードは、「現在のプロジェクト」の分離コードで使用されますaspx.cs

の構造体の実装System.Data DataTable

とそのstored procedure、に使用/割り当てられますSqlCommand

public sealed class AppDb
{
    public sealed class SqlTableMeta
    {    
      //id -for usage by jquery, name for the DataTable returnd in the next block of code
        public static DbTbl Time = new DbTbl(HTDB_Tables.TblTime, HTtIDs.tblTime);

    }
    public sealed class SqlSProcMeta
    {

        public static SProc Time = new SProc(HTSPs.SP_GetTimesWithCustomerNames,
                                             HTtIDs.SProcTime,
                                             HTSPs.GetTimesWithCustomerNames.SqlParLst("3571", "9", "2012", "1"));
    }

}

私が見たいのは

プロジェクトがデータを取得するために必要な追加コードのフットプリントが最小になること

だから私は、データベースとの実際の相互作用を行っている2番目の部分だと思います

テストが完了したらすぐに Helpers セクションに移動し、code behindすべてのアプリケーションのセクションから除外する必要があります。

次は、すべての準備とデータ設定を実行に移すコードです。

private DataTable GetDbTable(DbTbl dbTbl, SProc Sprc)
{
    SQLDBInteraction.DataContainer DC_Time = new SQLDBInteraction.DataContainer();

    //ParmsTime- a class instace, for passing a set of required parameters to final stage
    SQLDBInteraction.SqlParamList ParmsTime = new SQLDBInteraction.SqlParamList();
    
    ParmsTime.SqlCmd.CommandType = CommandType.StoredProcedure;

    //using the stored procedure struct:  assigend to Sqlcommand as its CommandText 
    ParmsTime.SqlCmd.CommandText = Sprc.Name;

    //using stored procedure parameters list - allso via a struct above codes
    ParmsTime.SqlCmd.Parameters.AddRange(Sprc.SpParList.ToArray());

    //using DataTable struct to assign the data table a name
    ParmsTime.TableName = dbTbl.Name;

    return DC_Time.LocalTbl_V3(ParmsTime);
}

最終段階: SQL データベースの相互作用

public class SQLDBInteraction
{

    public class SqlParamList
    {

        public SqlCommand SqlCmd = new SqlCommand();
        public List<SqlParameter> SP_Params = new List<SqlParameter>();
        
        public string TableName;
        public string SelectCommand;
        ///public SqlCommandType SelectedCmdType;
    }

    public class DataContainer
    {


        public DataTable LocalTbl_V3(SqlParamList Params)
        {
            SqlConnection sqlConnection;
            DataTable retDt = new DataTable(Params.TableName);
            SqlDataAdapter sqlDataAdapter;

            using (sqlConnection = new SqlConnection(WebConfigurationManager.ConnectionStrings["useyourwebconfigconnection"].ConnectionString))
            {
                sqlConnection.Open();

                using (Params.SqlCmd.Connection = sqlConnection)
                {

                    using (sqlDataAdapter = new SqlDataAdapter(Params.SqlCmd.CommandText, sqlConnection))
                    {
                        if (sqlDataAdapter.SelectCommand.Parameters.Count > 0 == false)
                        {
                            sqlDataAdapter.SelectCommand = Params.SqlCmd;
                            sqlDataAdapter.Fill(retDt);
                        }
                    }

                }

            }
            return retDt;
        }



   }


}

これは単なるテストですが、非常に高速に動作し、非常に簡単に実装できます。個人または小規模ビジネスでの使用に完全に適合します。

コメントは大歓迎です...

ありがとう

于 2012-12-11T17:43:21.960 に答える