この出版物では、実際のアプリケーションでEntity Framework(EF)を使用した個人的な経験を共有し、このフレームワークの使用に関するいくつかの有用なヒントを提供します。
私は.NETプラットフォームでエンタープライズアプリケーションを7年以上開発しており、この間にいくつかのORMライブラリを試しましたが、新しいプロジェクトにはEntity Framework Code Firstを使用しています。
最初、名前が示すように、このアプローチでは、アプリケーションデータを格納するデータベースが最初にコードを使用して記述され、次にフレームワーク自体がそれを作成または更新することを想定していました。 ただし、多くの開発者は、データベースが最初に作成され、オブジェクトがそれにマッピングされるときに、まったく逆のアプローチを使用することを選択しました。 これは、データがほとんど常に最前線にあり、OracleやMSSQL Serverなどのかなり高度なDBMSが使用されているエンタープライズアプリケーションに特に便利です。 テーブルの数が100を超える場合、EFデザイナーは好きではありません。 したがって、Code Firstは、非常に便利で非常に便利なものとして個人的に私に認識されました。
繰り返しになりますが、私の意見では、エンタープライズアプリケーションの主なものは、アプリケーションではなくデータです。 アプリケーションは行き来し、新しいものに置き換えられ、データは残り、何年も使用されます。 したがって、どのアプリケーションでも、データベースは常に、アプリケーションではなくデータベース設計者によって作成されます。
既製のデータベースがすでにある場合に最初にすることは、テーブルに一致するクラスを作成することです。 手動でこれを行うのは非常に面倒なので、次のようにします。
ヒント番号1。 テーブルベースのクラス生成
ここから取得できるT-SQLスクリプトは実際に機能し、非常に便利です。
ヒント番号2。 再生ビュー
EFは、データを受信して保存する最初のリクエストの処理時間が非常に長いことで知られています。 この状況を修正するには、再生成ビューを使用できます。
ビューの再生成は、最初のリクエストが実行されたときにフレームワーク内で発生するものです。 このプロセスは、アプリケーションのコンパイル段階に転送できます。これにより、最初の要求の速度が大幅に低下します。 EFの異なるバージョンでは、方法はわずかに異なります。 私はこのアプローチを使用し、完全に満足しました。
ヒント番号3。 DetectChangesによる一括データ更新
デフォルトでは、フレームワークは、データベースに保存する必要がある変更を自動的に追跡するように構成されています。
たとえば、次の簡単な例を考えてみましょう。
var dbContext = new MyDbContext(); // for(var i=0;i<1000;i++) { dbContext.People.Add(new Person());//!!! } // dbContext.SaveChanges();
それを起動することにより、多くの人はおそらく、データベースの実際のクエリではなく、dbContext自体へのオブジェクトの挿入にほとんどの時間が費やされることに驚くでしょう。 実際、DbContext内でデータが変更されると、多くのチェックやその他のちょっとした研究が行われます 。詳細については、 こちらを参照してください 。 これを回避するには、DbContextクラスの変更の追跡をオフにし、これらの変更を検出するDetectChanges()メソッドを明示的に呼び出します。 したがって、このコードははるかに高速に動作します。
var dbContext = new MyDbContext(); // dbContext.Configuration.AutoDetectChangesEnabled = false; // for(var i=0;i<1000;i++) { dbContext.People.Add(new Person());// } dbContext.ChangeTracker.DetectChanges(); // . // dbContext.SaveChanges();
ヒント番号4。 フレームワークが作成するSQLクエリに従います
これはかなり普遍的なアドバイスであり、おそらくすべてのORMに適用できますが、何らかの理由で多くの人がそれを忘れています。 そして、アプリケーションを実装し、プロファイラーを開いて、50のデータベースクエリを見てかなり単純なフォームを表示した後、彼らは非常に驚いています。
一方、フレームワークは、いくつかの最適化のためのメカニズムを提供します。 これらのメカニズムの中で最も有名なものは、同じクエリで子オブジェクトを「プル」するIncludeメソッドです。 例:
var dbContext = new MyDbContext(); // Person Address var person = dbContext.People.Include(p=>p.Address).FirstOrDefault(); // var address = person.Address;
ヒント番号5。 データベースロジックを分離する
EFという名前には「フレームワーク」という言葉がありますが、データベースの操作を単純化するためだけに、通常のライブラリとして使用できます。
ほとんどの書籍やプレゼンテーションでは、次のようなコードが表示されます。
// MVC public class PersonController: Controller { // EF AppDbContext dbContext; public PersonController(AppDbContext dbContext) { this.dbContext = dbContext; } public IActionResult ViewPerson(int id) { var person = dbContext.People.First(p=>p.Id == id); return View(person); } }
このコードの問題は、アプリケーションのすべての部分をEntity Frameworkに緊密にバインドすることです。 これ自体は良いことでも悪いことでもありませんが、データへのアクセスのアーキテクチャを変更する必要がある場合は、人生が著しく複雑になることを理解する必要があります。 そして、たくさんのオプションがあるかもしれません:
- 特定のリクエストが非常に遅いことが突然わかり、それをストアドプロシージャまたはビューに置き換えることにしました
- 異なるDbContextで受信したデータを保存するのがどれほど難しいかを知って驚くでしょう
- 自明ではないデータ更新ロジックが必要な場合、コントローラー内にTransactionScope、DbConnectionクラスが表示されることに驚くでしょう。
- データベースを操作するためにコードを再利用することを考えます。
- EFの代わりにNHibernateを使用することにしました
- SOAアーキテクチャを使用して、Webサービスを通じてデータの取得と保存を開始してみませんか?
Repositoryと呼ばれるクラスのDAL(DataAccessなど)と呼ばれるプロジェクト内でのみEFを使用する場合のアプローチが好きです。たとえば:
// Person public class PersonRepository: IPersonRepository { public Person GetPerson(int personId) { var dbContext = new AppDbContext(); var person = dbContext.People.First(p=>p.Id == id); return person; } public void SavePerson(Person person) { var dbContext = new AppDbContext(); var dbPerson = dbContext.People.First(p=>p.Id == person.Id); dbPerson.LastName = person.LastName; ..... dbContext.SaveChanges(); return person; } }
アプリケーションはオブジェクトについてのみ知っており、データベースからオブジェクトを取得する方法と、データベースにオブジェクトを保存する方法しかわからないため、このアプローチは優れています。 私を信じて、これはあなたの人生をずっと楽にします。