简体   繁体   English

使用专用类和构造函数通过asp.net C#初始化SQL事务的存储过程

[英]Using a Dedicated Class & Constructor to initialize Stored Procedure for SQL Transaction via asp.net C#

I will try to be as Concise as I can be, please .. bear with me, as it should be very simple ... 我会尽量做到简洁, ..忍受,因为它应该很简单...

  • the goal: 目标:

    trying to universalize a specific section of a project, that is dealing with the SQL databse transactions . 试图通用化项目的特定部分,即处理SQL databse transactions

a side note 旁注

to assist you with your answer, I've pasted the folowing (just for Reference) 为了帮助您回答问题,我粘贴了以下内容(仅供参考)

a Usage-Code : GetTestOfTablTime() returns a DataTable 一个用法代码: GetTestOfTablTime()返回一个DataTable

class : SQLDBInteraction this is another Class - responsible for the final(SQL transaction) stage class: SQLDBInteraction这是另一个类-负责最终(SQL事务)阶段

in this code below I am constructing what I Call: " Stored Procedure's Meta Data " 在下面的这段代码中,我正在构造所谓的“ 存储过程的元数据

that class is the one that holds all of the SQL Db SPs : 该类是包含所有SQL Db SP的类:

HTSPs (HT is the company's aliases) HTSPs (HT是公司的别名)

this class is holding each SP (requierd) parameter s 此类持有每个 SP (必需) parameter s

HTSPs class contains another sub Class, for all SP s Names, it only has const string s For Each SP name HTSPs类包含另一个子类,对于所有SP名称,它仅包含const string对于每个SP名称

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();            
    }
}

so the issue is: how do I initialize the constractor ? 所以问题是: 如何初始化承包商?

what is the Proper way to have your simple customised StoredProcedure " MetaData " 什么是拥有简单的自定义StoredProcedureMetaData ”的正确方法

Iv'e currently Completed the implementation of the Method below (apart from that issue...) Iv'e目前已完成以下方法的实施(除了该问题...)

USAGE 用法

this is a method that returns DataTable while using the HTSPs class / constuctor 这是在使用HTSPs class / constuctor HTSPs返回DataTable的方法

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);
 }

UPDATE 更新

the last lines of the code above is trying to implement the parmeters assignment , 上面代码的最后几行试图实现参数分配,

thus it will no longer be required to use : 因此将不再需要使用:

SQLDBInteraction.SqlParamList.SP_Params (which is List<SqlParameter> ) SQLDBInteraction.SqlParamList.SP_Params (即List<SqlParameter>

and instead i would really like to be able to use 相反,我真的很想能够使用

SQLDBInteraction.SqlParamList.SqlCmd.Parameters

that way as it is already used for most of the requierd steps to interact with the Database, 这种方式已经用于大多数与数据库交互的必要步骤,

so this is how i will drop some unnecessery usage of extra variables 所以这就是我将删除多余变量的一些不必要用法的方式

while in same time i wanted to assign SqlCmd ( parmsTime.SqlCmd.Parameters.Add(......) ) 同时我想分配SqlCmd( parmsTime.SqlCmd.Parameters.Add(......)

with the Struct - SPTime Real SqlParameters 使用Struct- SPTime 实际 SqlParameters

... instead of using the strings that reperesnts their name as it is now ... 而不是使用现在代表其名称的字符串

Eg parameter.name - ( SPTime.ParNameMonth, someValue ) 例如parameter.nameSPTime.ParNameMonth, someValue

final stage- sql trasaction 最后阶段-SQL事务

the SQLDBInteraction Class that does the transaction 执行事务的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;
        }

I will really appreciate it if someone will find what am I doing wrong with the part of the stored procedure's Parameters Assigned to the SQL Command 如果有人发现存储过程的分配给SQL Command的参数部分出现了问题,我将非常感激

so at last ... this is my own answer to the 'problem'. 所以最后……这是我对“问题”的回答。

as there will always be opportunities to fine-tune ...and polish it even more, 因为总会有微调的机会...并进一步完善它,

though I did find , a way to implement the solution . 尽管我确实找到了一种解决方案的方法。

for starters : 对于初学者 :

Summary 摘要

connecting between a 3 stages proccess - the data extraction , as follows: 在三个阶段的过程之间进行连接-数据提取 ,如下所示:

1'st stage : assigning the name and id's for the table and its stored procedure within the struct 第一阶段:在结构中为表及其存储过程分配名称和ID

2'nd stage : constructing the sql parameter collection / List <SqlParameter> for the final sql command . 第二阶段:为最终的sql命令构造sql参数集合/ List <SqlParameter>

the 3'rd stage : by using these struct s to format / construct the sql command, 所述3'rd阶段:通过使用这些struct s至格式化/构造SQL命令,

will in return, get a System.Data DataTable as requested, via the sql instructions in the stored procedure... naturally. 作为回报,将通过存储过程中的sql指令获取所请求的System.Data DataTable

prepering a background - for code ReUse 准备背景-代码重用

these first 2 blocks of code are sotred in two separated files 前两个代码块存放在两个单独的文件中

the first file is for holding the sql databse schema 第一个文件用于保存sql databse模式

table names , tables (custom) IDs , Columns names , and stored procedures names and parameters. 表名称,表(自定义)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'
}

the Second file is a general usage Helper nameapace , that stores all Helper classes, 第二个文件是常规用法Helper nameapace ,它存储所有Helper类,

and one of the classes (next block of code) , is the one that hodls the struct s 其中一个类(下一个代码块)是将struct shold的类之一

one for the table and another for the stored procedure, 一个用于表,另一个用于存储过程,

these two, will be assinged, later in the application's code behind . 这两个将在后面的应用程序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; }
                }
            }

so both of the codes above are in two separated files ... 所以上面的两个代码都在两个单独的文件中...

meaning codes above could be used in every application i need to create, 上面的含义代码可用于我需要创建的每个应用程序中,

so it'll be very easy to implement after this initial background work done. 因此完成此初始后台工作后,将非常容易实现。

  • second part 第二部分

implementation in current project. 当前项目中的实施。

the next codes are used in the "current project" code behind aspx.cs 接下来的代码在aspx.cs后面的“当前项目”代码中使用

the implementation of struct for the System.Data DataTable System.Data DataTable的struct的实现

and its stored procedure , that will be used / assigned to the SqlCommand 及其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"));
    }

}

the final two steps that could have been in one , though what i want to see is 最后的两个步骤可能合而为一,尽管我想看到的是

that the project would have the smallest footprint of extra codes needed to get the data 该项目将具有获取数据所需的额外代码最小的占用空间

so i guess the second part that is doing the actual interaction with database 所以我想第二部分正在与数据库进行实际交互

should be soon after tests are complete moved to the Helpers section and out of the code behind section of every application . 测试完成后应尽快移至“帮助程序”部分,并移出每个应用程序code behindcode behind部分。

so next are codes that will gather all preperations and data setup into action 接下来是将所有准备工作和数据设置收集到一起的代码

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);
}

the final stage: sql database interaction 最后阶段: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;
        }



   }


}

this is only a test, yet it works very fast and very easy to implemet , it will fit perfectly as it is for personal or small buisness use 这只是一个测试,但是它运行非常迅速且易于实现,非常适合个人或小型商务用途

comments are very welcome ... 评论是非常欢迎的...

thanks 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM