【问题标题】:Passing values between Windows form and a database在 Windows 窗体和数据库之间传递值
【发布时间】:2017-02-08 21:06:55
【问题描述】:

我在尝试为大学作业构建 Windows 表单解决方案时遇到问题,希望有人能指出我的错误。

解决方案是关于移动商店。我有两个课程,Apple 和 Android 表格。我需要读取数据库表中的数据,将条目分类为 Android 或 Apple 手机,然后在表单加载时将所有手机显示在列表中。

我可以成功地对手机进行分类,但是在尝试阅读条目时,我总是在表单的列表中两次看到相同的条目,而第二个条目根本没有出现。

我知道我在连接时犯了一个愚蠢的错误,但我找不到它!

这是我的代码:

public abstract class MobilePhone {
    private Int32 phoneID;
    private string operatingSystem;
    private string make;
    private string model;
    public enum Condition { Poor, Fair, Good, Mint };
    private Condition condition;
    private decimal originalPrice;
    private DateTime datePurchase;
    private string description;
    private clsDataConnection dbConnection;

    //constructor
    public MobilePhone(string make, string model, decimal originalPrice, DateTime datePurchase, Condition condition, string description) {
        this.make = make;
        this.model = model;
        this.originalPrice = originalPrice;
        this.datePurchase = datePurchase;
        this.condition = condition;
        this.description = description;
    }

不完整,但这就是相关的:

public class ApplePhone : MobilePhone {
    decimal ApproxValue;
    public ApplePhone(string make, string model, decimal originalPrice, DateTime datePurchase, Condition condition, string description)
        : base(make, model, originalPrice, datePurchase, condition, description) {
    }

Android 类相同,但其他功能不同。

class Shop {
    clsDataConnection dbConnection;
    const int NotAdded = -1;  // invalid primary key
    private string name;
    private decimal ApproxValue;
    private Int32 phoneID;
    private string operatingSystem;
    private string make;
    private string model;
    private MobilePhone.Condition condition;
    private decimal originalPrice;
    private DateTime datePurchase;
    private string description;
    Int32 Index;
    private List<MobilePhone> phonesForSale;

    //constructor
    public Shop(string name) {
        this.name = name;
    }

    MobilePhone phone;

    public void SelectAll() {
        dbConnection = new clsDataConnection();
        dbConnection.Execute("SellectAllPhones");
    }

    public void FilterByOperatingSystem(string operatingSystem) {
        dbConnection = new clsDataConnection();
        dbConnection.AddParameter("@OperatingSystem", operatingSystem);
        dbConnection.Execute("FilterByOperatingSystem");
    }

    public Int32 Count {
        get {
            //return the count of records
            return dbConnection.Count;
        }
    }

    public string DescribeCurrentPhone(int Index) {
        Int32 phoneID;
        string make;
        string model;
        MobilePhone.Condition condition;
        decimal originalPrice;
        DateTime datePurchase;
        string description;

        phoneID = Convert.ToInt32(phonesForSale[Index].PhoneID);
        make = Convert.ToString(phonesForSale[Index].Make);
        model = Convert.ToString(phonesForSale[Index].Model);
        condition = phonesForSale[Index].GetCondition;
        originalPrice = Convert.ToDecimal(phonesForSale[Index].OriginalPrice);
        datePurchase = Convert.ToDateTime(phonesForSale[Index].DatePurchased);
        description = Convert.ToString(phonesForSale[Index].Description);
        //set up a new object of class list item             
        string listItemText = make + " " + "|" + " " + model + " " + "|" + " " + condition + " " + "|" + " " + "£" + Math.Round(originalPrice, 2) + " " + "|" + " " + datePurchase.ToShortDateString() + " " + "|" + " " + description;
        return listItemText;
    }

    public List<MobilePhone> Allphones {
        get {
            phonesForSale = new List<MobilePhone>();
            int count = Count;
            Index = 0;
            while (Index < count) {
                phoneID = Convert.ToInt32(dbConnection.DataTable.Rows[Index]["PhoneId"]);
                operatingSystem = Convert.ToString(dbConnection.DataTable.Rows[Index]["OperatingSystem"]);
                make = Convert.ToString(dbConnection.DataTable.Rows[Index]["Make"]);
                model = Convert.ToString(dbConnection.DataTable.Rows[Index]["Model"]);
                string conditionString = Convert.ToString(dbConnection.DataTable.Rows[Index]["Condition"]);
                originalPrice = Convert.ToInt32(dbConnection.DataTable.Rows[Index]["OriginalPrice"]);
                datePurchase = Convert.ToDateTime(dbConnection.DataTable.Rows[Index]["DatePurchased"]);
                description = Convert.ToString(dbConnection.DataTable.Rows[Index]["Description"]);
                // Set Condition
                if (conditionString == "Poor") {
                    condition = MobilePhone.Condition.Poor;
                } else if (conditionString == "Fair") {
                    condition = MobilePhone.Condition.Fair;
                } else if (conditionString == "Good") {
                    condition = MobilePhone.Condition.Good;
                } else if (conditionString == "Mint") {
                    condition = MobilePhone.Condition.Mint;
                }
                //check Operating System
                if (operatingSystem == "IOS") {
                    phone = new ApplePhone(make, model, originalPrice, datePurchase, condition, description);
                    //ApproxValue = ApplePhone.CalculateApproximateValue();
                } else if (operatingSystem == "Android") {
                    phone = new AndroidPhone(make, model, originalPrice, datePurchase, condition, description);
                    //ApproxValue = AndroidPhone.CalculateApproximateValue();
                }
                Index++;
                phonesForSale.Add(phone);
            }
            return phonesForSale;
        }
    }

表格代码为:

public partial class FormMain : Form {
    public FormMain() {
        InitializeComponent();
        Shop shop = new Shop("");
    }

    private void FormMain_Load(object sender, EventArgs e) {
        DisplayItems("");
    }

    protected int DisplayItems(string operatingSystem) {
        Shop MyShop = new Shop("");
        Int32 RecordCount;
        Int32 Index = 0;
        Int32 PID;

        if (operatingSystem != "") {
            MyShop.FilterByOperatingSystem(operatingSystem);
        } else {
            MyShop.SelectAll();
        }

        RecordCount = MyShop.Count;
        ArrayList MyPhones = new ArrayList();
        while (Index < RecordCount) {
            // I Suspect this line is the problem but don't know how to fix it
            PID = MyShop.Allphones[Index].PhoneID
            string listItemText = MyShop.DescribeCurrentPhone(PID);
            //add the new item to the list
            MyPhones.Add(listItemText);
            //increment the index
            Index++;
        }
        listBox1.DataSource = MyPhones;
        return RecordCount;
    }

我不习惯连接到数据库,所以任何建议都会有所帮助!

【问题讨论】:

  • 第一个问题。方法 SelectAll()。这是在做什么?它似乎没有返回任何数据,它只是调用 dbConnection.Execute("SellectAllPhones")
  • 它执行这个存储过程,以便我可以读取它的结果数据(表格)

标签: c# winforms visual-studio


【解决方案1】:

下面是您建立的数据库连接的替代示例

  List<MyPhone> myIPhoneList = new List<Myphone>();
   List<MyPhone> myAndroidList = new List<Myphone>();

SqlConnection myDBConnection = new SqlConnection("MyConnectionString"); //DB Connection
            SqlCommand dbCommand = new SqlCommand("SelectAllPhones"); //Stored Procedure
            SqlDataReader recordReader = dbCommand.ExecuteReader(); //Execute

            //Read records return in to phone objects
            while (recordReader.Read()) {
                var phoneField1 = recordReader["PhoneField1FromDatabase"];
                var phoneField2 = recordReader["PhoneField2FromDatabase"];
                //etc...

                var myPhone = new MyPhone();
                myPhone.Name = phoneField1;
                //etc...
                if (myPhone.OS == "iPhone")
                 myIPhoneList.Add(myPhone);

               if (myPhone.OS = "Android")
                 myAndroidList.Add(myPhone);
            }

【讨论】:

  • 自己创建 2 个手机列表,每个操作系统 1 个,然后将这些列表的内容填充到您的表单列表中
  • 还要看封装。您的数据库连接应该位于一个单独的类中,该类将您的数据返回到理想情况下的业务类,该业务类反过来会创建电话列表并将其返回到您的表单。
  • 非常感谢,我发现我不需要为这个项目使用数据库,所以我会很好,但我会在我的另一个项目上使用你的建议解决这个问题,谢谢。
【解决方案2】:

真的只是对 Wheels 答案的一个转折,

我会亲自在存储过程中放置​​一个过滤器。

SqlCommand dbCommand = new SqlCommand("SelectAllPhones"); //存储过程

变成这样:

using (SqlConnection conn = new SqlConnection())
{
  using (SqlCommand cmd = new SqlCommand("SelectAllPhones", conn))
  {
    cmd.Parameters.Add(new SqlParameter() { ParameterName = "@OS", SqlDbType = SqlDbType.VarChar, Direction = ParameterDirection.Input, Value = phoneOS });
    cmd.CommandType = CommandType.StoredProcedure;

    SqlDataReader reader = cmd.ExecuteReader();

    while (reader.Read())
    {
      // load your data...

    }

  }
}

只是因为为每个班级拖动两组电话数据(android/iphone)几乎没有意义。你也可以只拉回你需要的数据。

当然,存储过程需要更新以适应参数。

类似: AND PhoneOS = @OS

需要附加到您的 SQL 条件。

clsDataConnection dbConnection;我不知道 - 这是第三方库还是您编写但未包含的类?

public Int32 Count
{
    get
    {
        //return the count of records
        return dbConnection.Count;
    }
}

dbConnection.Count 似乎很不标准。读起来不像是在尝试获取行数,更多的是连接数 - 这在此处无效。

dbConnection.DataTables[0].Rows.Count;将是使用现有代码确定行的更好方法,因为目前它看起来好像您在计算数据库连接的数量,这不是您所追求的 - 如果使用我的或 Wheels 将是多余的,因为您不需要事先知道您要处理多少行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2015-12-07
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多