Entity FrameworkまたはRepositoryを実装する理由

抽象化? 抽象化が必要なのは誰ですか?

EFはMSの最もクールなORMです。 habrahabr.ru/post/157267それは本当にクールです。 このようなシステムを開発するには、あらゆる方向で非常に費用がかかります。 CodeFirsのこと、データベース設計の知識、はい! SQL自体の知識は必要ありません。これは素晴らしいことです。 しかし、すべてがとてもバラ色ですか?

ジュリーラーマンは多くを語ることができますmsdn.microsoft.com/en-us/magazine/ff898427.aspx

画像

何にも似ていませんか?

これは、Repository + UoWの実装です。 だから、EFを使用するときにあらゆる種類のラッパーを作成するのは無駄ですか?

EFはめちゃくちゃ人気のあるテクノロジーであり、ストレージに適したプロバイダーを見つけるのは困難です。

EF(およびリポジトリ)の主なアイデアは、サブジェクトレイヤーをストレージレイヤーから分離することです。 しかし、なぜですか?

すべてがシンプルであるため、ストレージとアイテムを痛々しく変更することなく、独立しています。

いつストレージを変更する必要がありますか?


私はそれを決してしたく​​ないが、彼らが言うように「決して言ってはいけない..」。 私は、ストレージの2つの戦闘レイヤーと別のデモがあるプロジェクトに取り組んでいます。 クライアント自身がデータの保存方法を選択します。

抽象化の上に抽象化を構築し、すでに実装されていることを行う必要がありますか?


答えは、特定のプロバイダーの互換性にあります。 そのようなプロバイダーの開発者の1人であるYevhen Shchyholyev www.infoq.com/articles/multiple-databasesが互換性と言っているのは次の とおりです。 直感的に理解された問題は、開発者自身によって強化されます。

ここにそれらのいくつかがあります。

データ型



Entity Frameworkは、限られた.NET型のセット(符号付き整数、Single、Double、Decimal、String、Byte []、TimeSpan、DateTime、DateTimeOffset、Boolean、Guid)をサポートしています。 ただし、このリストのすべての.NETタイプがデータベースでサポートされているわけではありません。


型は永遠の問題です。 つまり、あるプロバイダー(つまりプロバイダー)で実行された1つのスクリプトが、別のプロバイダーで同じ結果をもたらさない場合があります。

DateTimeOffsetのサポート


DataTimeOffsetは、最も問題のある.NETタイプです。 SQL Server MS 2008、Oracle、およびSQLiteではサポートされていますが、SQL Server MS 2005、MySQL、またはPostgreSQLではサポートされていません。これらのデータベースにはタイムゾーンオフセットを保存できるDateTimeがないためです。


私たちに生じた問題は、日付がUTCで保存されていたが、SQLightでのEFが永続的にLocalに戻ったことでした。 マッピングを使用しているため、問題は簡単に解決されました。

性能


特定のデータベースの特定の機能が考慮されない場合、あるデータベースではLINQクエリをより速く処理でき、別のデータベースではより遅く処理できる可能性があります。

LINQメソッドによって実行されるデータのページ分割.Skip()/。Take()は、最も高価な操作の1つです。 SQL ServerのSkip / Takeとは異なり、Oracleは内部サブクエリでソートを行う2つのサブクエリを生成します。これはパフォーマンスに悪影響を与える可能性があります。 他のデータベースでは、特にインデックス付けできない列でソートが行われる場合、ページネーションは非常に非効率的であることに注意してください。


ここで最も興味深いのは、さまざまなプロバイダーについて、独自のLINQクエリを作成する必要があることです。 別の興味深いシナリオ:彼らはコンテキストへのクエリの束でいくつかの機能を書き、すべてがうまく機能します。 しかし、アプリケーションはクロスしているため、これが別のプロバイダーでどのように機能するかを確認する必要があります。 クエリの一部が無効になることがわかりました。 関係ありません-最適化。 すべて順調です。 問題は、最適化がソースプロバイダーとの作業にどのように影響したかです。

リクエストの制限


EFでは、開発者はLINQ to EntitiesまたはEntity SQL、あるいはその両方の組み合わせを使用してクエリを作成できます。 いずれの場合でも、そのような要求はEFエンジンによって式ツリーとして中間表現に変換され、SQLクエリを生成するためにEFプロバイダーに送信されます。 EFは元々SQL Server用に開発されたため、特定のデータベースに対して正しいSQLを生成するために、EFプロバイダーが元の式ツリーを大幅に変換しなければならない場合があります。 ただし、これは常に可能とは限りません


それはミッション不可能を明確に言います。 SQL SQLはプロバイダーごとに異なります。 これは、リクエストが効果的ではないという事実でさえありませんが、アプリケーションの実行を台無しにする可能性があるという事実です。

関連するMSDNセクションでは、これらの機能はすべてすべてのEFプロバイダーでサポートされていると述べています。

「このセクションでは、すべてのデータプロバイダーでサポートされ、すべてのクエリテクノロジーで使用できる標準関数について説明します。」

DBMSごとに機能が異なるため、このセクションは過度に楽観的であるように思われ、互換性のすべての可能性実現できない場合があります。


こちらがリンクです。 しかし、誰でもではなく、一連のサードパーティプロバイダーの主要な開発者は、 ミッションは不可能だと言います。

おわりに


この記事では、Microsoft以外のSQL Serverデータベース用のEFアプリケーションの開発中に発生する最も一般的な問題について簡単に説明しようとしました。 間違いなく、この記事では他の多くの側面が注目されていません...


つまり、これらは、説明されている問題を超えて発生する可能性のあるすべての問題ではなく、熊手に立って初めて学習できる問題です。

まとめると。



EFは優れた抽象化であり、他の抽象化と同様に、その主な欠点(実装)がないわけではありません。 この記事で説明されている問題は、懐疑論者の頭からではなく、口からではなく、プロバイダーのプロバイダーから直接のものです。

プロバイダーはさまざまな企業によって開発されており、1つのプロジェクトでさまざまなメーカーのプロバイダーを使用すると、互換性の問題がはるかに多くなると確信しています。 forums.mysql.com/read.php?174、614148,614148

EFをラップして互換性の問題を吸収するこの抽象化の助けを借りて、説明されているすべての問題を簡単に回避できるため、 NO EFとは言いません。

PS



「自転車」を実装するために必要な可能性のあるものについては、技術的な例のみが考慮されます。リポジトリとローションを使用できる理由と使用する理由はもっと多くあります。



All Articles