C# Windows窗体应用中三层体系结构的实现

C# Windows窗体应用中三层体系结构的实现,c#,sql-server,winforms,C#,Sql Server,Winforms,我试图使用三层体系结构将数据插入数据库,但我被卡住了,无法继续 这是我的密码 首先是UI部分: public void assignField() { string maritalCondition = ""; string sex = ""; assignObj.Registered_Date = dateTimePicker1_Date.Value; assignObj.First_Name = txt_Fir

我试图使用三层体系结构将数据插入数据库,但我被卡住了,无法继续

这是我的密码

首先是UI部分:

    public void assignField()
    {
        string maritalCondition = "";
        string sex = "";

        assignObj.Registered_Date = dateTimePicker1_Date.Value;
        assignObj.First_Name = txt_FirstName.Text;

        if (comboBox2_MaritalStatus.SelectedIndex == 0)
        {
            maritalCondition = "Single";
        }
        else
            maritalCondition = "Married";

        assignObj.Marital_Status = maritalCondition;

        if (RadioButton_Male.Checked == true)
            sex = "Male";
        else
            sex = "Female";
        assignObj.Gender = sex;

        this.txt_Age.Text = Convert.ToInt32(age).ToString();
    }

    private void btnRegister_Click(object sender, EventArgs e)
    {
        assignField();
    }
其次是中间层:

public class CustomerDataType
{
    private DateTime registered_Date;
    private string first_Name;
    private int age;
    private string marital_Status;
    private string gender;

    public DateTime Registered_Date
    {
        get { return registered_Date; }
        set { registered_Date = value; }
    }

    public string First_Name
    {
        get { return first_Name; }
        set { first_Name = value; }
    }

    public int Age
    {
        get { return age; }
        set { age = value; }
    }

    public string Marital_Status
    {
        get { return marital_Status; }
        set { marital_Status = value; }
    }

    public string Gender
    {
        get { return gender; }
        set { gender = value; }
    }

    public void insertInfo()
    {
        CustomerDataAccess insertObj = new CustomerDataAccess(Registered_Date, First_Name, Age, Marital_Status, Gender);

        insertObj.insertCustomerInfo();
    }
}
最后是数据访问层:

public class CustomerDataAccess
{
    public CustomerDataAccess(DateTime Registered_Date, string First_Name, int Age, string Marital_Status, string Gender)
    {
        this.registrationDate = Registered_Date;
        this.fName = First_Name;
        this.userAge = Age;
        this.marriageStatus = Marital_Status;
        this.userGender = Gender;
    }

    SqlConnection con;
    SqlCommand cmd;

    DateTime registrationDate;
    string fName = "";        
    int userAge;
    string marriageStatus;
    string userGender;

    public void insertCustomerInfo()
    {
         try
         {  
            con = new SqlConnection("Data Source=LAKHE-PC;Initial Catalog=Sahakari;Integrated Security=True");
            con.Open();
            cmd = con.CreateCommand();
            cmd.CommandText = "sp_registerCust";
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add("@Registered_Date", SqlDbType.DateTime);
            cmd.Parameters["@Registered_Date"].Value = registrationDate;
            cmd.Parameters.Add("@First_Name", SqlDbType.VarChar);
            cmd.Parameters["@First_Name"].Value = fName;
            cmd.Parameters.Add("@Age", SqlDbType.Int.ToString());
            cmd.Parameters["@Age"].Value = userAge;
            cmd.Parameters.Add("@Marital_Status", SqlDbType.VarChar);
            cmd.Parameters["@Marital_Status"].Value = marriageStatus;
            cmd.Parameters.Add("@Gender", SqlDbType.VarChar);
            cmd.Parameters["@Gender"].Value = userGender;

            cmd.ExecuteNonQuery();
            con.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
}

在这里,使用存储过程并没有问题,并且可以从SQLServer轻松地将数据插入表中。但在windows窗体中,它不会在表中插入数据。请帮助我。

您的中间层由包含属性中所需值的类组成。与其手动编写数据访问,不如尝试使用实体框架(EF),它可以为您实现这一点。 您可以找到一个快速入门示例,它向您展示了如何使用它

实体框架没有手动映射字段并执行查询,而是这样做,这意味着您只需将值分配给对象的属性并调用SaveChanges()——SQL代码由EF自动创建和执行


为了进一步阅读,还可以找到很多内容,您的中间层由包含属性中所需值的类组成。与其手动编写数据访问,不如尝试使用实体框架(EF),它可以为您实现这一点。 您可以找到一个快速入门示例,它向您展示了如何使用它

实体框架没有手动映射字段并执行查询,而是这样做,这意味着您只需将值分配给对象的属性并调用SaveChanges()——SQL代码由EF自动创建和执行


为了进一步阅读,还有很多要查找的内容

我将做如下操作

UI

CustomerHandler custHandler = new CustomerHandler();
// create Customer object and pass to insert method
if (custHandler.InsertCustomer(new Customer(){
    FirstName = txt_FirstName.Text, Registered_Date =dateTimePicker1_Date.Value,
    //decalare other parameters....
    ))
{
    // insert Success, show message or update label with succcess message
}
在我的BL中

public  class CustomerHandler
{
    // in BL you may have to call several DAL methods to perform one Task 
    // here i have added validation and insert 
    // in case of validation fail method return false
    public bool InsertCustomer(Customer customer)
    {
        if (CustomerDataAccess.Validate(customer))
        {
            CustomerDataAccess.insertCustomer(customer);
            return true;
        }
        return false;
    }
}
在我的DAL中

// this is the class you going to use to transfer data across the layers 
public class Customer
{
    public DateTime Registered_Date { get; set; }
    public string FirstName { get; set; }
    //so on...

}

public class CustomerDataAccess
{
    public static void insertCustomer(Customer customer)
    {
        using (var con = new SqlConnection("Data Source=LAKHE-PC;Initial Catalog=Sahakari;Integrated Security=True"))
        using (var cmd = con.CreateCommand())
        {
            con.Open();
            cmd.CommandText = "sp_registerCust";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Registered_Date", customer.Registered_Date);
            cmd.Parameters.AddWithValue("@FirstName", customer.FirstName);
            // so on...
            cmd.ExecuteNonQuery();

        }

    }

    internal static bool Validate(Customer customer)
    {
        // some validations before insert 
    }
}

我会做下面这样的事情

UI

CustomerHandler custHandler = new CustomerHandler();
// create Customer object and pass to insert method
if (custHandler.InsertCustomer(new Customer(){
    FirstName = txt_FirstName.Text, Registered_Date =dateTimePicker1_Date.Value,
    //decalare other parameters....
    ))
{
    // insert Success, show message or update label with succcess message
}
在我的BL中

public  class CustomerHandler
{
    // in BL you may have to call several DAL methods to perform one Task 
    // here i have added validation and insert 
    // in case of validation fail method return false
    public bool InsertCustomer(Customer customer)
    {
        if (CustomerDataAccess.Validate(customer))
        {
            CustomerDataAccess.insertCustomer(customer);
            return true;
        }
        return false;
    }
}
在我的DAL中

// this is the class you going to use to transfer data across the layers 
public class Customer
{
    public DateTime Registered_Date { get; set; }
    public string FirstName { get; set; }
    //so on...

}

public class CustomerDataAccess
{
    public static void insertCustomer(Customer customer)
    {
        using (var con = new SqlConnection("Data Source=LAKHE-PC;Initial Catalog=Sahakari;Integrated Security=True"))
        using (var cmd = con.CreateCommand())
        {
            con.Open();
            cmd.CommandText = "sp_registerCust";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@Registered_Date", customer.Registered_Date);
            cmd.Parameters.AddWithValue("@FirstName", customer.FirstName);
            // so on...
            cmd.ExecuteNonQuery();

        }

    }

    internal static bool Validate(Customer customer)
    {
        // some validations before insert 
    }
}

此位看起来不正确:
cmd.Parameters.Add(“@Age”,SqlDbType.Int.ToString())-当然您只需要
SqlDbType.Int
小提示:自动属性以简化=减少bug(这不是代码的问题,但每个人都应该使用):提示:如果您已经有
CustomerDataType
-那么就使用它!在UI层中,创建其实例并设置其属性,在数据访问层中,在
insertCustomerInfo
方法中使用该类型-并非每个属性的所有单独参数…..登录SQL Server时,您使用的是应用程序使用的同一用户吗?如果没有,请确保在应用程序中运行SP的用户具有执行权限。这是一篇较旧的文章,但值得一读。您的“风格”是“将自定义业务实体组件作为输入和输出传递”,此位看起来不正确:
cmd.Parameters.Add(“@Age”,SqlDbType.Int.ToString())-当然您只需要
SqlDbType.Int
小提示:自动属性以简化=减少bug(这不是代码的问题,但每个人都应该使用):提示:如果您已经有
CustomerDataType
-那么就使用它!在UI层中,创建其实例并设置其属性,在数据访问层中,在
insertCustomerInfo
方法中使用该类型-并非每个属性的所有单独参数…..登录SQL Server时,您使用的是应用程序使用的同一用户吗?如果没有,请确保在应用程序中运行SP的用户具有执行权限。这是一篇较旧的文章,但值得一读。您的“风格”是“将自定义业务实体组件作为输入和输出传递”