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

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

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

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

4906閲覧

登録しようとしているデータが既にDBに存在する場合、エラーメッセージを表示したい

Eltk

総合スコア51

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

ASP.NET MVC Framework

ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2021/03/07 09:18

編集2021/03/08 12:27

前提・実現したいこと

個人開発で在庫管理アプリを作っております。

商品を登録時に、商品番号(や商品名など)について、DBに既に存在しているものがあれば、
登録させないようにし、「既に登録されています」とエラーメッセージを表示させたいです。

よろしくお願いいたします。

該当のソースコード

※Item.vb(商品モデル)

VisualBasic

1Imports System.ComponentModel 2Imports System.ComponentModel.DataAnnotations 3Imports System.ComponentModel.DataAnnotations.Schema 4 5Namespace Models 6 Public Class Item 7 <Key()> 8 <DisplayName("商品番号")> 9 <Required(ErrorMessage:="{0}は必須です。")> 10 <Index(IsUnique:=True, ErrorMessage:="こちらの{0}は既に登録されています。")> 11 <DatabaseGenerated(DatabaseGeneratedOption.None)> 12 <Range(10000000, 99999999, ErrorMessage:="{0}は8桁で入力してください。")> 13 Public Property ItemId As Integer 14 15 <DisplayName("商品名")> 16 <Required(ErrorMessage:="{0}は必須です。")> 17 <StringLength(16, ErrorMessage:="{0}は{1}文字以内で入力してください。")> 18 Public Property ItemName As String 19 20 <DisplayName("カテゴリー番号")> 21 <Required(ErrorMessage:="カテゴリー名は必須です。")> 22 <StringLength(3, ErrorMessage:="{0}は{1}桁以内で入力してください。")> 23 Public Property CategoryId As String 24 25 <DisplayName("商品単価")> 26 <Required(ErrorMessage:="{0}は必須です。")> 27 <Range(0, 99999, ErrorMessage:="{0}は5桁以内で入力してください。")> 28 Public Property UnitPrice As Integer 29 30 <DisplayName("カテゴリー")> 31 Public Overridable Property Category As Category 32 33 <DisplayName("発注書")> 34 Public Overridable Property OrderSheets() As ICollection(Of OrderSheet) 35 36 <DisplayName("返品書")> 37 Public Overridable Property ReturnSheets() As ICollection(Of ReturnSheet) 38 39 End Class 40End Namespace

試したこと

以下のように、Index(IsUnique:=True)を追加するところまではわかったのですが、
「ErrorMessage:="こちらの{0}は既に登録されています。」の箇所について
ErrorMessageに対して、プロパティが見つかりませんと表示されました。

VisualBasic

1<Index(IsUnique:=True, ErrorMessage:="こちらの{0}は既に登録されています。")> 2Public Property ItemId As Integer

※SurferOnWww様よりご回答いただきまして、試行しました分を追記いたします。
1つ目
イメージ説明
2つ目
イメージ説明

補足情報(FW/ツールのバージョンなど)

統合開発環境
Visual Studio2019
(言語:VB.NET、プロジェクトテンプレート:ASP.NET Webアプリケーション MVC)

MVCフレームワークのバージョン
5.2.7

データベース
SQL Server

使用PC
Windows10

※平日は仕事のため、返信が19:30以降になります。(22時以降は返信が翌日になることが多いです)
※休日の返信は不定期です。
申し訳ございませんが、どうぞよろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

DB が何だか書いてないのですが(そういう情報は必ず質問に書きましょう)、SQL Server であろうと想像してレスします。

以下のように、Index(IsUnique:=True)を追加するところまではわかったのですが、

それは思い違いです。EF Code First で DB を生成する際、それを付与したプロパティに該当するテーブルの列に一意インデックス制約を付与するということで、質問者さんが期待する、

「既に登録されています」とエラーメッセージを表示させたいです。

ということにはならないはずです。

制約に違反すれば例外がスローされるので、例外による何らかのメッセージが出るでしょうけど、そこでアプリは終わってしまうということになるはずです。

商品番号(や商品名など)について、

商品番号は主キーのようですので PK 制約違反を(Index(IsUnique:=True) は不要)、商品名には Index(IsUnique:=True) を付与して一意インデックス制約を付与し、Controller で SaveChange する際 try - catch でそれらの例外を捕捉してエラーメッセージを表示するということにしてはいかがですか?

それには以下の記事が参考になりそうです。(検証はしてないので保証の限りではありませんが)

EF6とSQL ServerでUniqueKey違反の例外をキャッチするにはどうすればよいですか?
https://www.it-swarm.jp.net/ja/c%23/ef6%E3%81%A8sql-server%E3%81%A7uniquekey%E9%81%95%E5%8F%8D%E3%81%AE%E4%BE%8B%E5%A4%96%E3%82%92%E3%82%AD%E3%83%A3%E3%83%83%E3%83%81%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%82%88%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/1054647724/

ちなみに上の記事の SqlException.Number の 2627 が PK 制約違反、2601 が一意インデックス制約違反です。

【追記】

上に「検証はしてないので保証の限りではありませんが」と書きましたが、紹介した記事の 2 つ目の回答の通りのコードで SqlException をキャッチできました。それで目的は果たせるはずです。お試しください。

投稿2021/03/08 03:16

編集2021/03/08 09:40
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Eltk

2021/03/08 11:06 編集

>SurferOnWww様 回答いただき、ありがとうございます。 データベースの情報を追記いたしました。 おっしゃられた記事の2つ目の回答を参考にチャレンジしたのですが、VBへの変換で詰まってしまいまして、3つ目の回答を参考に再度書き直してみました(エラーメッセージの表示は、いったんMsgBoxで仮代用)が、うまくキャッチできませんでした。 3つ目の回答ではダメなのでしょうか。 ※上記のエラーを添付させていただきますので、一度ご確認いただけますでしょうか。 ※質問を分けた方が良い場合は、ご指摘くださいませ。
退会済みユーザー

退会済みユーザー

2021/03/08 11:55

> 3つ目の回答ではダメなのでしょうか。 ダメですね。DbContext.SaveChanges メソッドがスローする例外は DbUpdateException, DbUpdateConcurrencyException などで、SqlException を直接補足することはできません。
Eltk

2021/03/08 12:30

>SurferOnWww様 承知しました。では、2つ目の方法で実装しようと思うのですが、 先程コメントしました通り、変換がうまくいきませんでした。 画像を追加いたしましたので、再度ご助力いただけませんでしょうか。 ※下線のエラー部は、全て「宣言されていません」というエラーです。 変換サイトを使って試行した結果になります。 ※質問を分けた方が良い場合は、ご指摘くださいませ。
退会済みユーザー

退会済みユーザー

2021/03/08 13:07

別にスレッドを立てて C# ⇒ VB.NET の変換の仕方を聞いたら?
退会済みユーザー

退会済みユーザー

2021/03/09 03:33 編集

追加された画像のコードを見てみましたが、Exception を catch していて「2つ目の方法」とは違いますよ。訳の分からないままいろいろやってギブアップし、やりかけのコードを投げたとしか思えないのですが。 質問者さんにとっての問題は catch の部分だと思いますが、VB.NET にも catch when 構文、Null 条件演算子、Is 演算子はあるようで、なさそうなのは xxxxx is SqlException sqlExという type switch だけのはずです。そこを除いては自力で C# ⇒ VB.NET 変換でき、質問は type switch 部分のみになってしかるべきです。丸投げしないで自分で考えましょう。
Eltk

2021/03/09 09:51

>SurferOnWww様 承知しました。 もう少し、一人で考えてみて、それでも厳しそうなら別スレッドを立て質問し直します。 本質問についてはいったんクローズさせていただきます。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問