2009-07-17 8 views
1

J'utilise une base de données comme une sorte de cache - le but est de stocker des "faits" connus actuellement (les détails ne sont pas si intéressants). Cependant, il est crucial de ne pas insérer de doublons dans les faits. Pour ce faire, le code d'accès aux données actuel utilise insert ou ignore dans de nombreux endroits. Je voudrais utiliser le framework d'entité pour bénéficier de sa facilité de gestion; J'en ai assez d'écrire du code standard pour un autre sur une requête subtilement différente, et jusqu'ici le support d'Entity Framework pour les requêtes est génial.Entity Framework: équivalent de INSERT OU IGNORE

Cependant, je ne peux pas vraiment trouver un bon support pour ajouter de nouveaux faits - la manière évidente semble être simplement de construire de nouvelles Entités dans .NET, les ajouter au modèle, et enregistrer les changements dans la base de données. Cependant, cela signifie que je dois vérifier à l'avance si une ligne particulière existe déjà, car si l'insertion n'est pas autorisée. Dans le meilleur des cas, cela signifie des allers-retours supplémentaires, mais c'est généralement bien pire: auparavant ce code était très parallèle - l'insertion dupliquée occasionnelle n'aurait pas d'importance puisque la base de données l'ignorerait - mais maintenant non seulement je devrais vérifier si une ligne existe à l'avance, je devrais le faire dans des lots beaucoup plus petits (ce qui est généralement beaucoup plus lent en raison des frais généraux de transaction) car une seule ligne existante d'une insertion parallèle entraînera un retour en arrière de la transaction entière. Donc, est-ce que quelqu'un sait comment obtenir un comportement similaire en utilisant le framework d'entité? Pour être précis, j'aimerais pouvoir effectuer plusieurs insertions et laisser la base de données simplement ignorer les insertions qui sont impossibles - ou plus généralement, être capable d'exprimer le code de résolution de conflit côté serveur pour éviter des allers-retours inutiles et les transactions.

Si cela compte, j'utilise SQLite.

Répondre

1

Cette fonctionnalité peut être mise en œuvre via des procédures stockées (que l'infrastructure d'entité peut utiliser) sur les DB qui la prennent en charge (MSSQL, par exemple). Sur SQLite, ceux-ci ne sont pas supportés. Cependant, une solution simple existe pour sqlite aussi bien, à savoir utiliser des déclencheurs tels que les suivants:

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; 

Sinon, le déclencheur pourrait être mis en place pour vérifier directement la contrainte et ne soulever « ignorer » lorsque la contrainte est violé.