SQLマッピングオブジェクトの設計へのLINQの上のアドバイス
-
21-09-2019 - |
質問
私は、タイトルと次のテキストを願ってはっきりしている、私は正しい用語に精通していないよので、私は間違って何かを得るなら、私を修正してください。私が初めてLINQのORMを使用していて、次のように対処する方法を疑問に思っています。
私は2つのDBテーブルがあるとします:
User
----
Id
Name
Phone
-----
Id
UserId
Model
のLINQコードジェネレータは、エンティティ・クラスの束を生成します。
私は、自分のクラスとインタフェースラップこれらのLINQクラスを書きます
class DatabaseUser : IUser
{
public DatabaseUser(User user)
{
_user = user;
}
public Guid Id
{
get { return _user.Id; }
}
... etc
}
これまでのところは良いです。
今ではPhones.Where(p => p.User = user)
からユーザーの携帯電話を見つけることは簡単ですが、確かにAPIのcomsumersは、データを取得するための独自のLINQクエリを記述する必要はありませんので、私はどこかで関数やプロパティでこのクエリをラップする必要があります。
問題があるので、この例では、あなたがたIUserへの電話機のプロパティを追加したりはないでしょうか。
は、換言すれば、私のインターフェースは、具体的には(この場合、電話がたIUserに属していない)自分のデータベース・オブジェクトをモデル化するべきであり、または(それらが実際に単に概念的ユーザに関連付けられている機能およびプロパティのセットを提供していますその場合、それがありませんか)?
があり、両方のビューに欠点がいるようだが、この問題に対する標準的なアプローチがある場合、私は思ったんだけど。それとも知恵のいずれかの一般的な言葉は、あなたが共有することができます。
私が最初に考えたのは拡張メソッドを使用するが、実際にそれがこのケースでは動作しませんでした。
解決
私はインタフェースの背後に抽象LINQtoSQLエンティティにしようと、いくつかのひどい経験をしました。これは、しばらく前だったが、メモリからの主な問題は、それが全く関連を壊すということでした。あなたはCustomer
持っている場合たとえば、 - > Order
の関係を、あなたはICustomer
はそれがIOrder
sとしてCustomer
オブジェクトの内部コレクションのキャストするためにいくつかの厄介なマッピングを行う必要があることを意味するOrder
sのコレクション、で、IOrder
として公開終わります<。 / P>
次に、あなたはIOrder
は、バック渡されるときに我々はOrder
にキャストできるということを前提としなければなりません。そうでなければLINQtoSQLはそれに対処することはできませんが、その後、それは最初の場所でそこにインターフェイスを持つのポイントに反します。
私は強くあなたはあまり離れてエンティティクラスを試してみて、抽象しないことをお勧めします、LINQtoSQLは実際にそれらの任意の本当の魔法をかけていない、DataContextのは、彼らの永続性のライフサイクルを扱うので、彼らはテスト可能残るます。
私はインターフェイスの後ろに隠すように見ていることになる側面は、リポジトリ・スタイルのクラスを使用して、たとえば、DataContextのとの相互作用になります:
public interface IPhoneRepository
{
IEnumerable<Phone> GetPhonesForUser(User user);
}
public class L2SPhoneRepository : IPhoneRepository
{
private readonly MyDataContext context;
public L2SPhoneRepository(MyDataContext context)
{
this.context = context;
}
public IEnumerable<Phone> GetPhonesForUser(User user)
{
return context.Phones.Where(p => p.User == user);
}
}
他のヒント
あなたのインターフェイスは、あなたが使用するオブジェクトのための希望の方法をモデル化する必要があります。あなたは抽象的にしようとしているので、その後、消費者は、DBを照会する必要はありません。あなたはそれを財産、または別の関数の呼び出しを行うかどうか(すなわち、GetPhones())、完全にあなた次第です。あなたは完全に物事をラップしているので、あなたは、あなたのオブジェクトをロードする方法を深く/なまけに関するいくつかの選択をする必要があります。
あなたは、たIUserへの電話機のプロパティを追加し、それがNULL可能にする必要があります。
あなたは(GETUSERのような機能を実装する必要がありますよりも、APIの消費者が...)、クエリを記述する必要はありませんのでなど。
ここでAsp.net
内の記事ABTのn層アプリケーションの素敵なリストですIは、データベースの実際の構造と同様に、必ずしもシステムの他の部分に曝されるべきではなく、データ・アクセス・コードの実装の詳細であることがLinq2Sql関連するものを検討する傾向があります。
あなたのAPIは、他の人々によって消費されようとしている場合、それは凝集し、使いやすく、消費者が知っている必要はありませんもので雑然とないでなければなりません。私は、ユーザーと自分の携帯電話を扱っていた場合、私は本当にのdatacontextsまたは(ぐふ)データセットに関する知っている必要はありません。
また、L2Sとデータベースの無知あなたのコードの大部分を保つことによって、あなたが作る、簡単に時間のテストを持っていますスキーマの変更(ああ、今Userテーブルが作られたすべての変更の履歴を保持する必要があります)、あるいは変更完全にORMます。