質問: 私はDapperを使ってカスタムORMを構築しています。私は次の表を持っています: * ユーザー * 役割 * 許可 * RolePermission 私のsprocには2つの選択肢があります:基本的なユーザー情報の場合は1、ユーザー役割情報の場合は1。基本的なユーザー情報は、デシリアライズされてユーザーオブジェクトになります。 RolePermissionの情報は、デシリアライズされてカスタムのRolePermissionオブジェクトになり、次にUserオブジェクトにプログラムで関連付けられます。カスタムORMでオブジェクトグラフの実装をどの程度複雑にしますか?たとえば、EFは、User.UserRoles.Role.Nameのようなロール名を取得するために、すばらしく簡単なオブジェクト指向のアプローチを採用しています。しかし、これは、db fkの関連付けに基づいてエンティティ結合を自動的にマッピングする複雑で洗練されたf / wの使用によって実現されます。また、パフォーマンスのオーバーヘッドもあります。私の考えは、以下のようにエンティティクラスを作成することです: * MyCompany.Entities.Entity.User.User * MyCompany.Entities.Entity.User.RolePermission したがって、私のRolePermissionオブジェクトは、外部依存関係のないUserエンティティに完全に合わせられます。これにより、RolePermissionオブジェクトは、Userオブジェクトのコンテキストでできるだけ軽量に保たれます。他のエンティティ/ドメイン/用途をサポートするための追加のプロパティは必要ありません。これは、エレガントな(簡単で効果的で効率的な)ソリューションのようです。カスタムORMで複雑なオブジェクトを作成するこのタイプのアプローチに関するあなたの考えは何ですか?
回答: 私はいつもこのようなことをしていて、それは本当に簡単です。あなたは2つのクエリでそれを行います。 2つのクエリは同じsprocにあり、異なる結果セットを返すことも、データベースへの2つの別々の呼び出しにすることもできます。私は通常、複数の結果セットを返すことができるmssqlを使用していますが、後者を行います。 そこでまず、ユーザー(浅い)とオプションでロール情報(深い)を含むユーザーの詳細を照会しています。 ``` public IEnumerable GetUsers(int? userID, bool withDetails) { var users = db.Query(@" select * from dbo.Users u where (@userID IS NULL OR u.Id = @userID)", new { userID }); if (withDetails) { var rolePermissions = db.Query(@" select * from dbo.RolePermissions rp where rp.UserId IN (select val from dbo.udf_ConvertIntListToTable(@userId_list))", new { userId_list = String.Join(',', users.Select(s => s.UserId)) }); foreach(var user in users) { user.RolePermissions = rolePermissions.Where(w => w.UserId == user.UserId); } } } ``` いくつかのメモ: * dbo.udf_ConvertIntListToTableは非常によく確立されており、優れたパフォーマンスを発揮します。ウェブを検索すると、それを見つけることができます。あなたがそれを見つけることができなければ、私はそれを要点としてロードします。 * RolePermissionは外部ユーザー(私はUserIdを使用)への参照を持つ必要があります。また、そのクエリは、あなたが言及した追加のデータ(例えば、役割、権限など)をマップする可能性があります。 * 私は、上記をきれいにする拡張のトンがあります。私はできるだけ生のままにしておいたので、何が起こっているか見ることができます。 * これで、リストなどのための非常に軽いクエリ(withDetails = false)と、すべてのデータが集約ルート(User)に素早くラップされたより重いクエリが得られました。