質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Q&A

解決済

2回答

648閲覧

C# プロジェクトの分割方法

maam

総合スコア55

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

0グッド

0クリップ

投稿2019/01/31 02:55

編集2019/01/31 03:52

WindowsFormで画面を作成しています。
①生徒一覧画面 ②登録画面 ③編集画面 の3画面を作成しています。
C#でSQLServerに接続し、データを操作できる画面です。 
ここではSQL文を扱うプロジェクト(SQL)と画面の操作をするプロジェクト(Operation)でわけたいと思っています。
id:生徒番号
name1:名字
name2:名前
birthday:誕生日
post_code:郵便番号
adress:住所

Operationで情報の更新の操作を行っています。

C#

1//Operation 2 3 //OKボタン押下時 4 if (result == DialogResult.OK) 5 { 6 //MemberInformation member = new MemberInformation(); 7 //MemberInformationManager.Update(member); 8 //member.FirstName = textSei.Text; 9 //member.LastName = textMei.Text; 10 //DateTime birthday; 11 //member.Birthday = DateTime.TryParse(year + "/" + month + "/" + day, out birthday) ? year + month + day : null; 12 //member.IsMan = manBt.Checked; 13 //member.IsWoman = womanBt.Checked; 14 //member.PostCode = yuubin1 == "" && yuubin2 == "" ? null : yuubin1 + yuubin2; 15 //member.Adress = textJyusyo.Text; 16 17 // 接続文字列の取得 18 var connectionString = ConfigurationManager.ConnectionStrings["sqlsvr"].ConnectionString; 19 20 // データベース接続の準備 21 using (var connection = new SqlConnection(connectionString)) 22 using (var command = connection.CreateCommand()) 23 { 24 try 25 { 26 // データベースの接続開始 27 connection.Open(); 28 29 // SQLの準備 30 command.CommandText = @" UPDATE MEMBER_MASTER SET name1 = @name1, name2 = @name2, birthday = @birthday, gender = @gender, post_code = @post_code, " 31 + "adress = @adress, last_updated = @last_updated, version = version+1 WHERE id = @id"; 32 command.Parameters.Add(new SqlParameter("@id", dgv.Cells[0].Value.ToString())); 33 command.Parameters.Add(new SqlParameter("@name1", sei)); //姓の登録 34 command.Parameters.Add(new SqlParameter("@name2", mei)); //名の登録 35 DateTime birthday; 36 command.Parameters.Add(new SqlParameter("@birthday", 37 DateTime.TryParse(year + "/" + month + "/" + day, out birthday) ? birthday : (object)DBNull.Value)); //生年月日の登録 38 command.Parameters.Add(new SqlParameter("@gender", seibetu)); //性別の登録 39 command.Parameters.Add(new SqlParameter("@post_code", 40 yuubin1 == "" && yuubin2 == "" ? (object)DBNull.Value : yuubin1 + yuubin2)); //郵便番号の登録 41 command.Parameters.Add(new SqlParameter("@adress", jyusyo == "" ? (object)DBNull.Value : jyusyo)); //住所の登録 42 command.Parameters.Add(new SqlParameter("@last_updated", DateTime.Now)); //更新日の登録 43 44 // SQLの実行 45 command.ExecuteNonQuery(); 46 } 47 catch (Exception exception) 48 { 49 Console.WriteLine(exception.Message); 50 throw; 51 } 52 finally 53 { 54 // データベースの接続終了 55 connection.Close(); 56 } 57

データの更新部を上記のように書いていました。
それを

C#

1 2 //OKボタン押下時 3 if (result == DialogResult.OK) 4 { 5 //MemberInformation member = new MemberInformation(); 6 //MemberInformationManager.Update(member); 7 //member.FirstName = textSei.Text; 8 //member.LastName = textMei.Text; 9 //DateTime birthday; 10 //member.Birthday = DateTime.TryParse(year + "/" + month + "/" + day, out birthday) ? year + month + day : null; 11 //member.IsMan = manBt.Checked; 12 //member.IsWoman = womanBt.Checked; 13 //member.PostCode = yuubin1 == "" && yuubin2 == "" ? null : yuubin1 + yuubin2; 14 //member.Adress = textJyusyo.Text; 15 } 16 17

で書いてみたのですが、
”追加情報:パラメーター化クエリ '(@id int,@name1 nvarchar(4000),@name2 nvarchar(4000),@birthday n' に必要なパラメーター '@name1' が指定されていません。”
とエラーが出てしまいます。

ちなみにSQL文のプロジェクトとクラスは下記です。

C#

1//SQL 2 3 public static Boolean Update(MemberInformation member) 4 { 5 // 接続文字列の取得 6 var connectionString = ConfigurationManager.ConnectionStrings["sqlsvr"].ConnectionString; 7 8 // データベース接続の準備 9 using (var connection = new SqlConnection(connectionString)) 10 using (var command = connection.CreateCommand()) 11 { 12 try 13 { 14 // データベースの接続開始 15 connection.Open(); 16 17 // SQLの準備 18 command.CommandText = @" UPDATE MASTER SET name1 = @name1, name2 = @name2, birthday = @birthday, gender = @gender, post_code = @post_code, " 19 + "adress = @adress, last_updated = @last_updated, version = version+1 WHERE id = @id"; 20 command.Parameters.Add(new SqlParameter("@id", member.Id)); 21 command.Parameters.Add(new SqlParameter("@name1", member.FirstName)); //姓の登録 22 command.Parameters.Add(new SqlParameter("@name2", member.LastName)); //名の登録 23 DateTime birthday; 24 command.Parameters.Add(new SqlParameter("@birthday", 25 DateTime.TryParse(member.Birthday, out birthday) ? member.Birthday : (object)DBNull.Value)); //生年月日の登録 26 string seibetu = member.IsMan ? "1" : "2"; 27 command.Parameters.Add(new SqlParameter("@gender", seibetu)); //性別の登録 28 command.Parameters.Add(new SqlParameter("@post_code", member.PostCode == "" ? (object)DBNull.Value : member.PostCode)); //郵便番号の登録 29 command.Parameters.Add(new SqlParameter("@adress", member.Adress == "" ? (object)DBNull.Value : member.Adress)); //住所の登録 30 // SQLの実行 31 command.ExecuteNonQuery(); 32 } 33 catch (Exception exception) 34 { 35 Console.WriteLine(exception.Message); 36 throw; 37 } 38 finally 39 { 40 } 41 return true; 42 } 43 } 44

C#

1public class MemberInformation 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public String FirstName { get; set; } 6 public String LastName { get; set; } 7 public String Birthday { get; set; } 8 public Boolean IsMan { get; set; } 9 public Boolean IsWoman { get; set; } 10 public String PostCode { get; set; } 11 public String Adress { get; set; } 12 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/01/31 03:26

どれがコメントでどれがコードなのかもわからないしデータがどこでどのように初期化されているかもわからないしどこでストップしたのかもわからないので、問題解決できるよう整理して書いてください。 あてずっぽうの回答しかできません。 とりあえずはグローバル変数が多すぎるので、メソッド内部ですべての変数をリテラルで初期化し、エラーの出る行番号を書いてください。それだけでも随分違います。
Zuishin

2019/01/31 03:27

行番号と書きましたが、行番号だけではこちらで特定できないので、それがどの行にあたるのかもはっきりと書いてください。
maam

2019/01/31 03:49

すみません。 SQLのクラス(MemberInformationManager)の // SQLの実行 command.ExecuteNonQuery();を抜けるとエラーがでました
Zuishin

2019/01/31 03:52

リテラルでない初期化 int i = a; string s = t; リテラルでの初期化 int i = 0; string s = "Foo";
Zuishin

2019/01/31 03:54

多分参考書やネットの情報なども、わからないところは飛ばして読んでいるんだと思いますが、それは「ななめ読み」と言って読んだうちには入りません。 わからないところは調べ、聞けるときには聞いてください。
maam

2019/01/31 04:07

わかりました。ありがとうございます。
guest

回答2

0

メソッド public static Boolean Update(MemberInformation member) の
タイポ(スペルミス)に1票入れておきます。

投稿2019/01/31 03:17

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

csharp

1 if (result == DialogResult.OK) 2 { 3 MemberInformation member = new MemberInformation(); 4 //MemberInformationManager.Update(member); 5 member.FirstName = textSei.Text; 6 member.LastName = textMei.Text; 7 DateTime birthday; 8 member.Birthday = DateTime.TryParse(year + "/" + month + "/" + day, out birthday) ? year + month + day : null; 9 member.IsMan = manBt.Checked; 10 member.IsWoman = womanBt.Checked; 11 member.PostCode = yuubin1 == "" && yuubin2 == "" ? null : yuubin1 + yuubin2; 12 member.Adress = textJyusyo.Text; 13 MemberInformationManager.Update(member); 14 }

とりあえずこうやってUpdateを下にもってきてください。話はそれからです。


解決に至るために、IDを設定するというもうひと作業が必要だったっぽいです。


補足
設定すべきプロパティを忘れないようにするには例えばこうします。

csharp

1public class MemberInformation 2{ 3 public int Id { get; private set; } //全部private setでもいいかもね。 4 //public string Name { get; set; } = string.Empty 5 public string FirstName { get; set; } = string.Empty 6 public string LastName { get; set; } = string.Empty 7 public string Birthday { get; set; } = string.Empty 8 private bool isMale = true; 9 public bool IsMan { get=> isMale; set(val) => isMale = value } //構文あやしい //こういう構造はとてもよくない。IsMan = true; IsWoman = true;をどうやって防ぐの? 10 public bool IsWoman { get=> !isMale; set(val) => isMale =!value; } //構文あやしい 11 public string PostCode { get; set; } = string.Empty 12 public string Adress { get; set; } = string.Empty 13 private MemberInformation() {} //デフォルトコンストラクタをprivateにする 14 public MemberInformation(int id, string name, string first, string last, string birth, bool male, string postal, string address) 15 { 16 ID = id; 17 Name = name;//以下引数を全部セットしてく。 18 } 19 public MemberInformation(int id) => Id = id; //オーバーロードをどの程度用意するかは用途にあわせて。最低でもidは強制すべき。 20}

投稿2019/01/31 03:07

編集2019/01/31 07:41
papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maam

2019/01/31 03:50

前回に引き続きすみません。下へ持ってきました。
papinianus

2019/01/31 04:08

それで全く同じエラーですか? あとざっと見たところ、ここのブロックでPostCodeがnullにされて、Updateの中ではEmptyのときだDBNull.Valueになるので、結果nullが維持されてしまう問題もありますね。yubin1とyubin2が両方""のときにわざわざnullにする意味がないです(+で足してエラーもないし、結果も正しい)。どちらか片方でもnullのとき、エラーを回避するため、nullにするならまだ分かりますが。
maam

2019/01/31 04:14

処理としては通りましたが、更新されずにSQLServerのデータがそのままの状態になりました。 確かにPostCodeは、yuubin1とyuubin2のどちらか片方が””ならnullで十分ですね。
papinianus

2019/01/31 04:18

> 処理としては通りましたが、更新されずにSQLServerのデータがそのままの状態になりました それは、前回の質問の、対策を、とってないからです。idは0です。idをセットしてください もし可能であればこのバグを自分で気付きやすくするためidが0のテストユーザをDBにインサート(SSMSなどC#以外から)することをすすめます。
papinianus

2019/01/31 04:23

> 確かにPostCodeは、yuubin1とyuubin2のどちらか片方が””ならnullで十分ですね 説明がへたでした。 `member.PostCode = yuubin1 == "" && yuubin2 == "" ? null : yuubin1 + yuubin2;` ↑ここを↓こう `member.PostCode = yuubin1 + yuubin2;` してください。
maam

2019/01/31 04:34

member.Id = Convert.ToInt32(dgv.Cells[0].Value); を追加し `member.PostCode = yuubin1 + yuubin2;` に書き直すことで実行できました><ありがとうございます。 同じようなことをする画面がありますので、そちらは全て自分で書けるように頑張ります。 本当にありがとうございます。
papinianus

2019/01/31 04:37

> 同じようなことをする画面 処理の意味合いが同じなのでしょうか、それとも入力からmemberinformationを作るという全く同じ作業をするということでしょうか。 後者であれば、補助関数かコンストラクタを書いて、同じミスを起こさないようにコードで保証すべきだと考えます。
maam

2019/01/31 05:13

登録画面としてINSERT文でも作成しないといけないので、 今回の要領と同じようにしていけばできるかなと思っています。 memberinformationは同じものを使います。
papinianus

2019/01/31 05:15

回答を追記します
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問