2009-07-17 13 views
1

私はデータベースをキャッシュの一種として使用しています。これは現在知られている "ファクト"を保存することです(詳細は興味深いものではありません)。しかし重大なことに、重複した事実を挿入することは避けたい。これを行うために、現在のデータアクセスコードは多くの場所で挿入または無視を使用します。エンティティフレームワーク:INSERT OR IGNOREと同等

私はエンティティフレームワークを使用して、その管理性の恩恵を受けることを望みます。私は微妙に異なるクエリではまだ別のための定型的なコードを書いていましたが、今のところEntity Frameworkのクエリのサポートは素晴らしく見えます。

しかし、実際には新しい事実を追加することはできません。明らかに、.NETで新しいエンティティを作成し、モデルに追加してデータベースに変更を保存することです。ただし、挿入が許可されていないため、特定の行がすでに存在するかどうかを事前に確認する必要があります。通常、このコードは非常に並行していました。データベースは無視されるため、重複した挿入は問題になりませんでしたが、並列挿入からの1つの既存の行だけがトランザクション全体のロールバックを引き起こすので、私はずっと小さなバッチ(トランザクションオーバーヘッドのために典型的には何倍も遅い)でこれを行う必要があります。

エンティティフレームワークを使用して同様の動作を取得する方法を知っている人はいますか?

具体的には、いくつかの挿入を実行して、不可能な挿入をデータベースが単純に無視できるようにしたいと思っています - より一般的には、不要なラウンドトリップを避けるためにサーバー側の競合解決コードおよび取引。

私はSQLiteを使用しています。

答えて

1

この機能は、それをサポートするDB(MSSQLなど)のストアドプロシージャ(エンティティフレームワークが使用できる)を使用して実装できます。 SQLiteでは、これらはサポートされていません。しかし、簡単な解決策、すなわち、次のようなトリガーを使用すること、ならびにSQLiteのために存在する:

CREATE TRIGGER IF NOT EXISTS MyIgnoreTrigger BEFORE INSERT ON TheTable 
FOR EACH ROW BEGIN 
    INSERT OR IGNORE 
     INTO TheTable (col1, col2, col3) 
     VALUES (NEW.col1, NEW.col2, NEW.col3); 
    select RAISE(IGNORE); 
END; 

あるいは、トリガが直接制約を検証するように設定し、唯一の制約が「無視する」上げることができます違反した。