Member 13235643 Ответов: 2

Прием пользовательского ввода и хранение его в иерархическом порядке в базе данных в приложении C#


Я новичок, пытаюсь разработать приложение c# windows form.

Я подготовил код для хранения 3 входных данных в базе данных:
3 поля: lvl, posid, upperposid.

Теперь мне нужно изменить код таким образом, чтобы пользовательский ввод был принят только в том случае, если "upperposid" уже существует в базе данных. А значения "upperposid" еще не хранятся в базе данных. Будет сохранено только одно значение "upperposid", и все данные, введенные пользователем, будут дочерними по отношению к этому " upperposid"

Например, если пользователь вводит данные как:
lvl=2, posid= "ребенок" и upperposid= " родитель",
тогда данные будут приниматься только в том случае, если значение "parent" существует по крайней мере один раз в столбце upperposid.
Итак, в качестве другого примера, если пользователь дает ввод:

lvl= " 3"
posid= " CIV"
upperposid= " RET"

Тогда данные будут приниматься и храниться только в том случае, если "RET" существует хотя бы один раз в столбце "upperposid".

Пожалуйста, руководство по этому вопросу. Пожалуйста, предоставьте сам код C#, если можете. Я привел код ниже. Спасибо

Что я уже пробовал:

//Code:
        //This is Class called "WBSMASTERDB"
        namespace Actual_Project
       {
       public class WBSMASTERDB
       {
        public static SqlConnection GetConnection()
        {
            string connStr = @"Data Source=
      (LocalDB)\v11.0;AttachDbFilename=C:\Users\ABC\Documents\Visual Studio
      2013\Projects\Actual Project\Actual Project\ActualProj_DB.mdf;Integrated
      Security=True;";
           SqlConnection conn = new SqlConnection(connStr);
           return conn;
       }
       public static void AddData(string posid, string lvl, string upperposid)
     {

               string insStmt = "INSERT INTO WBS_MASTER (posid, upperposid,lvl)
               VALUES (@lvl, @upperposid, @posid)";
               SqlConnection conn = GetConnection();
               SqlCommand insCmd = new SqlCommand(insStmt, conn);
               insCmd.Parameters.AddWithValue("@posid", posid);
               insCmd.Parameters.AddWithValue("@upperposid", upperposid);
               insCmd.Parameters.AddWithValue("@lvl", lvl);
               try { conn.Open(); insCmd.ExecuteNonQuery(); }
               catch (SqlException ex) { throw ex; }
               finally { conn.Close(); }
       }
       public static List<wbsmastercls> GetData()
       {
           List<wbsmastercls> DataList = new List<wbsmastercls>();
           SqlConnection conn = GetConnection();
           string selStmt = "SELECT * FROM WBS_MASTER";
           SqlCommand selCmd = new SqlCommand(selStmt, conn);
           try
           {
               conn.Open();
               SqlDataReader reader = selCmd.ExecuteReader();
               while (reader.Read())
               {
                   WBSMASTERCLS apc = new WBSMASTERCLS();
                   apc.posid = (string)reader["posid"].ToString();
                   apc.upperposid = (string)reader["upperposid"].ToString();
                   apc.lvl = (string)reader["lvl"].ToString();
                   DataList.Add(apc);
               }
               reader.Close();
           }
           catch (SqlException ex) { throw ex; }
           finally { conn.Close(); }
           return DataList;
       } } }

      //Code
    //This is Class called "WBSMASTER [Here the AddData() is called]"

     namespace Actual_Project
      {
     public partial class WBSMASTER : Form
     {

       public WBSMASTER()
       {
           InitializeComponent();
       }
       private void button1_Click(object sender, EventArgs e)
       {

               WBSMASTERDB.AddData(textBox1.Text, textBox2.Text,textBox3.Text);
               textBox1.Text = "";
               textBox2.Text = "";
               textBox3.Text = "";
       }

Richard Deeming

catch (SqlException ex) { throw ex; }

Пожалуйста, не делай этого. Вы только что уничтожили трассировку стека исключения, что сделает почти невозможным отследить реальную причину ошибки.

Если вам необходимо повторно создать исключение, используйте:
catch (SomeException ex) { throw; }


Но в этом случае, поскольку вы ничего не делаете с исключением, просто удалите catch пункт целиком.

2 Ответов

Рейтинг:
2

W∴ Balboos, GHB

Как правило, если вы создаете иерархические отношения данных в базе данных, у вас есть более чем одна таблица для этого.

В вашем случае upperposid лучше представить в виде отдельного списка значений, которыми вы управляете в отношении его содержимого, каким бы способом вы ни создавали значения upperposid.

Другая таблица будет содержать значения lvl и posid вместе со ссылкой на таблицу, содержащую верхний posid.

Они должны быть отношением внешнего ключа между двумя таблицами, поэтому вы не можете добавлять какие-либо значения, которые не находятся в upperposid.

Обратите внимание, что все это обрабатывается SQL, а не вашим кодом.

Однако ваш код должен использовать таблицу upperposid, чтобы предложить список допустимых значений для ввода, чтобы пользователь не мог ошибиться или иным образом испортить ситуацию.


Member 13235643

Но мне нужно реализовать логику в самом коде. Некоторая логика в AddData () {я предполагаю}, которая показывает пользователю какое-то сообщение об ошибке, если вход "upperposid" не совпадает ни с одним значением в таблице базы данных.

Я думал использовать оператор if..else или оператор IF EXISTS (), но я не знаю, где его использовать и как правильно написать.

W∴ Balboos, GHB

Здесь на ум приходят две мысли:
1) Вы делаете это для себя: почему бы не сделать это правильно?
2) это домашнее задание - и идея его заключается в том, чтобы вы учились, делая.

Кстати: IF EXISTS () - это SQL, так что если это приемлемо, то почему бы моему решению не быть приемлемым?

Рейтинг:
1

RickZeeland

Что-то вроде этого:

string sql = "SELECT COUNT(*) FROM WBS_MASTER WHERE upperposid = @upperposid";

using (SqlConnection conn = new SqlConnection(connString))
{
	SqlCommand cmd = new SqlCommand(sql, conn);
	cmd.ParametersAddWithValue("@upperposid", upperposid);
	try
	{
		conn.Open();
		Int32 count = (Int32) cmd.ExecuteScalar();
		return (count > 0);
	}
	catch (Exception ex)
	{
		Debug.Print(ex.Message);
		return false;
	}
}


Member 13235643

Это не работает. Это не дает исключения или хранения каких-либо данных в базе данных, когда пользователь нажимает кнопку Отправить после ввода данных.

RickZeeland

LocalDb может дать проблемы, а когда вы попробуете с обычной базой данных SQL Server ?
Строка строки insStmt = " INSERT INTO WBS_MASTER (posid, upperposid,lvl)
Значения (@lvl, @upperposid, @posid)";

неправильно я думаю, что значения posid и lvl переключаются.