1. ホーム
  2. c#

列挙型の使用と永続化のためのベストプラクティス

2023-08-26 11:37:32

質問

ここで、enum のような値 (例えば、enum.exe) を処理し、持続させるための最良の方法に関するいくつかの質問/議論を目にしました。 列挙型に適したデータの永続化 , NHibernateを使用してenumを永続化する方法 を参照してください)、そして私は一般的な同意が何であるかを尋ねたいと思います。

特に

  • これらの値は、コード内でどのように扱われるべきでしょうか?
  • どのようにデータベースに永続化させるか(テキストとして/数値として)?
  • 異なるソリューションのトレードオフは何ですか?

注: この質問に元々含まれていた説明を回答に移動しました。

どのように解決するのですか?

私の理解をまとめてみました。もし訂正があれば、遠慮なく編集してください。それでは、どうぞ。

コードの中で

コード中では、enumは言語固有のenum型(少なくともJavaとC#では)を使って処理するか、あるいは、enum型と同様に typeafe enum pattern" . 型安全性が失われる(そして、どの値が例えばメソッドのための正当な入力であるかを理解するのが難しくなる)ので、普通の定数(Integerまたは類似)を使用することは推奨されません。

これらの2つの選択は、どの程度の追加機能がenumに添付されるかに依存します。

  • もし、enum に機能の負荷を置きたいなら (それは良いことで、常に switch() することを避けるためです)、クラスが通常より適切です。
  • 一方、単純なenumのような値の場合、言語のenumは通常より明確です。

特に、少なくともJavaではenumは他のクラスから継承できないので、似たような動作をするenumが複数あり、それをスーパークラスに入れたい場合、Javaのenumは使えません。

列挙型の永続化

列挙型を持続させるために、各列挙型の値には一意の ID を割り当てる必要があります。これは整数か短い文字列のどちらかです。短い文字列は、ニモニック(DBAなどがデータベース内の生データを理解しやすくなる)であるため、好ましいです。

  • ソフトウェアでは、すべての列挙型は、列挙型(ソフトウェア内部で使用)とID値(永続化用)の間で変換するためのマッピング関数を持つ必要があります。いくつかのフレームワーク (例: (N) Hibernate) には、これを自動的に行うための限定的なサポートがあります。そうでなければ、enum 型/クラスにそれを置く必要があります。
  • データベースは、(理想的には) 各 enum に対して、有効な値をリストしたテーブルを含むべきです。1 つのカラムは ID (上記参照) であり、これは PK となります。追加のカラムは、例えば、説明のために意味をなすかもしれません。そのenumからの値を含むすべてのテーブルカラムは、この "enumテーブル"をFKとして使用することができる。これにより、不正な enum 値が決して永続化されないことが保証され、DB を自立させることができます。

このアプローチの 1 つの問題は、合法な enum 値のリストが 2 つの場所 (コードとデータベース) に存在することです。これは回避するのが難しいため、しばしば許容範囲と見なされますが、2 つの選択肢があります。

  • DB に値のリストのみを保持し、構築時に列挙型を生成します。エレガントですが、ビルドを実行するために DB 接続が必要であることを意味し、問題があると思われます。
  • コード内の値のリストを権威あるものとして定義する。実行時 (通常は起動時) に DB 内の値と照合し、不一致の場合は警告/中止を表示します。