Search code examples
c#.netmethodscall

How do I write a method which is supposed to get data from database to show on a form in C#


I'm a beginner to .net and could you guide me to right direction. My problem is based on the following code. Here I have 4 variations of same method and all 4 variations are working fine.

  1. I just want to know what is the recommended or standard way of doing this?

  2. Are all these forms of method ok?

Code explanation:
From a windows form I'm calling a viewAccount() method which is in bankAccount class. Its purpose is to get relevant bank account details of an employee from the database and then those details should be shown in the text boxes of calling form.

Also please note that I have reduced no of line to make it more readable. Appreciate your any help towards the right direction.

Thank you.

Example 01 - Method will return a bankAccount object with fields populated with data from the database

class bankAccount
{
    //Member fields...
    string acNo;
    string acName;
    string bank;
    string acType;
    frmShowAccount form=new frmShowAccount();

    public bankAccount viewAccount( string acNo )
    {
        this.acNo = acNo;

        using (SqlConnection newCon = new SqlConnection(db.GetConnectionString))
        {
            SqlCommand newCmd = new SqlCommand("SELECT Employee.Name, BankAccount.ac_name, BankAccount.bank_name, BankAccount.ac_type FROM BankAccount INNER JOIN Employee ON BankAccount.emp_id = Employee.Emp_ID WHERE (BankAccount.ac_no = @bankAccount)", newCon);

            newCmd.Parameters.Add("@bankAccount", SqlDbType.Char).Value = acNo;
            newCon.Open();
            SqlDataReader rdr = newCmd.ExecuteReader();
            rdr.Read();

            form.txtEmpName.text = rdr.GetString(0); //EmpName is not a member of bankAccount class
            this.acName = rdr.GetString(1);
            this.bank = rdr.GetString(2);
            this.acType = rdr.GetString(3);

            return this;
        }
    }
}

// CALLING THE ABOVE METHOD...

bankAccount newBA = new bankAccount();
newBA = newBA.viewAccount(txtACNo.text);  // A reference is set to the instance returned
txtACName.text = newBA.acName;  // Get the value of instance field to text box

Example 02 - Method will return a data reader and it will be used by the form to get data

    class bankAccount
    {
        string acNo;
        string acName;
        string bank;
        string acType;

        public SqlDataReader viewAccount( string acNo )
        {
            this.acNo = acNo;

            using (SqlConnection newCon = new SqlConnection(db.GetConnectionString))
            {
                SqlCommand newCmd = new SqlCommand("Same SELECT …”,newCon);

                newCmd.Parameters.Add()…
                newCon.Open();
                SqlDataReader rdr = newCmd.ExecuteReader();
                rdr.Read();

                return rdr;
            }
        }
    }

//CALLING THE ABOVE METHOD...
bankAccount newBA = new bankAccount();
SqlDataReader rdr = newBA.viewAccount(txtACNo.text) //A reference to hold the returning reader from the method call
txtACName.text = rdr.getString(1); //Get the value through the reader to text box

Example 03: this method want return values but explicitly assign values to the text boxes in the form

  class bankAccount
  {
        string acNo;
        string acName;
        string bank;
        string acType;
        frmShowAccount form=new frmShowAccount();

        public void viewAccount( string acNo )
        {
            this.acNo = acNo;

            using (SqlConnection newCon = new SqlConnection(db.GetConnectionString))
            {
                SqlCommand newCmd = new SqlCommand("Same SELECT …", newCon);

                newCmd.Parameters.Add()…
                newCon.Open();
                SqlDataReader rdr = newCmd.ExecuteReader();
                rdr.Read();

                // Setting values to the text boxes in the current instance of form
                form.txtName.text=rdr[0];
                form.txtACName.text=rdr[1];
                form.txtBankName.text=rdr[2];
                form.txtACType.text=rdr[3];         
            }
        }
    }

//CALLING THE ABOVE METHOD
bankAccount newBA = new bankAccount();
newBA.form.this; // reference 'form' which is in the 'bankAccount' class is set to current instance of the form object.

Example 04: this method want return any value. It will only initialize instance fields of the class with the data

    class bankAccount
    {
        string acNo;
        string acName;
        string bank;
        string acType;
        frmShowAccount form=new frmShowAccount();

        public void viewAccount( string acNo )
        {
            this.acNo = acNo;

            using (SqlConnection newCon = new SqlConnection(db.GetConnectionString))
            {
                SqlCommand newCmd = new SqlCommand("Same SELECT …)", newCon);

                newCmd.Parameters.Add()…
                newCon.Open();
                SqlDataReader rdr = newCmd.ExecuteReader();
                rdr.Read();

                form.txtName.text=rdr[0];
                this.acName=rdr[1];
                this.bank=rdr[2];
                this.acType=rdr[3];
        }
    }


// CALLING THE ABOVE METHOD
bankAccount newBA = new bankAccount();
txtACName.text = newBA.acName; // Text boxes get the data from account object's instance fields (probably through a get property)

Solution

  • Option 1 is your best bet, but:-

    a) The method accessing the database really should return a new BankAccount model object, rather than setting the properties of this:-

    class BankAccountModel
    {
      public string AccountNumber { get; set; }
      public string AccountName { get; set; }
      public string Bank { get; set; }
      public string AccountType { get; set; }
    
      public static BankAccountModel GetAccount(string accountNumber)
      {
        var account = new BankAccountModel()
        {
          AccountNumber = accountNumber,
        };
    
        using (SqlConnection newCon = new SqlConnection(db.GetConnectionString))
        {
            ...
    
            account.AccountName = rdr.GetString(1);
            account.Bank = rdr.GetString(2);
            account.AccountType = rdr.GetString(3);
        }
    
        return account;
      }
    }
    

    b) If you're making a WPF/Winforms/Webforms application, you'll want to investigate Data Binding rather than manually setting the values of your controls to the values of your model.

    var account = BankAccountModel.GetAccount(accountNumber);
    myControl.DataSource = account;
    

    (Or if you're making an ASP.NET MVC application, you just pass your model to the view):-

    var model = BankAccountModel.GetAccount(accountNumber);
    return View(model);
    

    c) It's usually helpful if your model doesn't have to concern itself with the way that it's being persisted. Eventually you'll want to pull the "GetAccount" method out of your Model class and into some dedicated data access code (e.g. a BankAccountRepository). This gives you better flexibility for situations where you need to control the lifecycle of your managed resources (e.g. the database connection), or if you need to obtain BankAccountModels from multiple sources:-

    class BankAccountModel
    {
      public string AccountNumber { get; set; }
      public string AccountName { get; set; }
      public string Bank { get; set; }
      public string AccountType { get; set; }
    }
    
    class BankAccountRepository
    {
      public BankAccountModel GetAccount(string AccountNumber)
      {
        ...
      }
    }