Scott Wlaschinの優れた書籍「ドメインモデリングは機能的:ドメイン駆動設計とF#でソフトウェアの複雑さに取り組む」を読み終えました。彼はデータベースアクセスにF#SQLタイププロバイダーを使用しています。
明白な質問を予想して、彼は(p260)ドメインの完全性をそのように保証することができないのでORMを使用しないように言います。たとえば、ORMはメールアドレスなどを検証できません。ネストされた選択肢タイプなどを処理できません。
ただし、本の前半では(手に負えないため、正確に引用できるといいので)、ワークフローの各セクションの境界を作成する方法を説明するときに、データを各セクションの境界で検証する必要があると述べ、セクション内のコードはすべて有効であると想定しています。
もしそうなら、ORMから出てコードに入るエンティティを境界を越えたものとして扱い、そこで検証しませんか?そうすることで、ORMのメリットを享受しながら、モデルの整合性を確保できます。
明確にするために、私は「F#ではオブジェクトリレーショナルマッパー(ORM)を使用しない傾向がある」と述べましたが、検証の問題のためではなく、Entity Frameworkのような大きなORMは非常にオブジェクト指向(驚き!)常に機能的なパラダイムとうまくかみ合うとは限りません。代わりに、F#ersはタイププロバイダーまたはDapperなどのより単純なライブラリを使用します。
「リレーショナルデータベースの操作」の章では、データベースを2つの異なる方法で扱うことができると言います。
適用されるケースは、データベースが他のアプリケーションと共有されているかどうか、データベースの設計方法などによって異なります。
更新:次の文が誤って解釈される可能性があることを理解しています。
Entity FrameworkやNHibernateのように、このすべてのマッピングを自動的に行うだけのものを使用できないのでしょうか。答えは「いいえ」であり、ドメインの整合性を確保したい場合ではありません。
つまり、ドメインモデルをORMを介してデータベースに直接変換すると、ドメインタイプの複雑さが大幅に失われます。 -「違法な状態を表現できないようにする」設計アプローチ。これは、ORMが制約、複雑な選択タイプなどを持つ単一ケースの共用体を処理する方法を知らないためです。
代わりに、ドメインオブジェクトを永続化用に特別に設計されたタイプ(「DTO」)に変換し、そのDTOをドメインタイプではなく永続化に使用することをお勧めします。 DTOを格納/ロードするには、EFまたはNHibernateを確実に使用できますが、そのように使用すると、そこから大きな価値が得られないため、通常、タイププロバイダーまたはDapperのような軽量マッパーを使用する方が簡単です。
本の次の段落を読むと、次のように書かれています。
典型的なランタイムライブラリではなくタイププロバイダーを使用することの特別な点は、SQLタイププロバイダーがコンパイル時にSQLクエリまたはSQLコマンドに一致するタイプを作成することですSQLクエリが正しくない場合、ランタイムエラーではなくコンパイル時エラーが発生します。 SQLが正しい場合、SQLコードの出力と正確に一致するF#レコードタイプが生成されます。
したがって、このアプローチは、C#で静的型付けが行うことと同じ保証をいくつか提供しているようです。つまり、型が揃わない場合、コンパイル時にエラーが発生します。