0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Entity Framework 6でNOT NULLだが空文字を許容したい時

Last updated at Posted at 2021-06-23

しばらくハマったのと、疑問があったのでメモしておきます。

環境

PostgreSQL 12.2, compiled by Visual C++ build 1914, 64-bit
EntityFramework6.Npgsql v6.4.3

作業の流れ

①あるテーブルempに列stを追加。Char(1)で、特定の文字を入れてステータスを管理する。"S"とか"T"とかが入る。また、空文字""は「指定なし」の意味となる。

②DBに①の列を追加。

③PostgreSQLは空文字とNullを区別するので、空文字以外にNullの状態まで管理するとバグの原因になると思い、NOT NULL制約を付与。

④既存のテーブルに列を追加するので、デフォルト値として空文字''を指定。

ALTER TABLE emp ADD COLUMN st char(1) NOT NULL DEFAULT '';

⑤これに併せて、エンティティクラスempにも、以下のプロパティを追加。

<Required>
<StringLength(1)>
Public Property st As String

⑥ところが、実際にEFを使っての更新プログラムにて、

rec.st = ""

の行を追加したところ、DbContext.SaveChagesでエラーに。

どうやらRequired属性を指定した為に引っかかっている模様。Required属性は、空文字を「未入力」として扱うということでしょう。DBのNOT NULLとそのまま対応付けられるわけではないので、注意が必要そうです。

⑦以下のようにすることで、空文字を許容するようになるとのこと。

<Required(AllowEmptyStrings:=True)>
<StringLength(1)>
Public Property st As String

参考:https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.requiredattribute.allowemptystrings?view=net-5.0

AllowEmptyStringsをTrueにして再度動かしてみると、空文字を指定してもエラーが出なくなった。
DBも正しく空文字が設定されており、問題なし。

懸念事項

ただ、上記のマイクロソフトのページに書かれている次の文言が気になる。

When you set AllowEmptyStrings to true for a data field, Dynamic Data does not perform validation and transforms the empty string to a null value. This value is then passed to the database.

If the database does not allow null values, it raises an error. To avoid this error, you must also set the ConvertEmptyStringToNull to false.

適当に翻訳すると

データフィールドのAllowEmptyStringsをtrueに設定すると、Dynamic Dataは検証を実行せず、空文字列をnull値に変換します。この値はその後データベースへと渡されます。

もしデータベースがnull値を許容しない場合、エラーを発生させます。このエラーを回避する為には、併せてConvertEmptyStringToNullをfalseに設定する必要があります。

今回、フィールドstは、DB側でNOT NULL制約を付与しているので、上記の説明の通りだと空文字を設定した時に値がNullに変換され、DB更新時にNOT NULL制約にひっかかってエラーが発生するはず。

しかしエラーは発生しておらず、データベースにもnullではなく空文字が設定されている。
念のためConvertEmptyStringToNull:=Trueを指定してみても、結果は同様。
つまり、ConvertEmptyStringToNullは動作していないように見える。

一体どういうことになっているのかわかる方がいたらコメントで教えて頂けると助かります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?