0

我会尽量简洁,..请耐心等待,因为它应该非常简单......

  • 目标:

    试图通用化项目的特定部分,即处理SQL databse transactions.

旁注

为了帮助您回答,我粘贴了以下内容(仅供参考)

一个使用代码:GetTestOfTablTime()返回一个DataTable

类:SQLDBInteraction这是另一个类 - 负责最终(SQL 事务)阶段

在下面的这段代码中,我正在构建我所说的:“存储过程的元数据

该类是包含所有 SQL Db SP 的类:

HTSPs(HT是公司的别名)

这个类正在持有每个 SP (必需的) parameter s

HTSPsclass 包含另一个子 Class,对于所有SP的 s 名称,它只有const strings 的 For EachSP名称

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元数据”的正确方法是什么

我目前已完成以下方法的实施(除了那个问题......)

用法

这是一个DataTable在使用HTSPs class/时返回的方法constuctor

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(......))

使用结构 -SPTime 真实 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 个阶段的过程 - 数据提取,如下所示:

第一阶段:为结构中的表及其存储过程分配名称和ID

第二阶段:List <SqlParameter> 为最终的sql命令构建sql参数集合。

第三阶段:通过使用这些structs来格式化/构造sql命令,

作为回报,将System.Data DataTable通过存储过程中的 sql 指令获得请求的结果……自然而然。

准备背景 - 代码重用

前 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'
}

第二个文件是一个通用的 Helper nameapace,它存储了所有 Helper 类,

并且其中一个类(下一个代码块)是持有structs 的类

一个用于表,另一个用于存储过程,

这两个,将在稍后的应用程序中分配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; }
                }
            }

所以上面的两个代码都在两个单独的文件中......

意思是上面的代码可以在我需要创建的每个应用程序中使用,

因此,在完成初始后台工作后,将非常容易实现。

  • 第二部分

在当前项目中实施。

后面的代码用在“当前项目”代码后面aspx.cs

struct 的实现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"));
    }

}

最后两个步骤可以合二为一,虽然我想看到的是

该项目将拥有最少的额外代码来获取数据

所以我猜第二部分是与数据库进行实际交互

应该在测试完成后不久移到 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 回答