Comment puis-je Insérer ou mettre à Jour (ou remplacer) un enregistrement à l'aide de NHibernate?
J'ai besoin d'écrire une ligne à la base de données, indépendamment de savoir si elle existe déjà ou pas. Avant d'utiliser NHibernate cela a été fait avec une procédure stockée. La procédure de tenter une mise à jour et si pas de lignes ont été modifiées, il serait de revenir à une insertion. Cela a bien fonctionné car l'application ne prend pas en charge si l'enregistrement existe.
Avec NHibernate, les solutions que j'ai trouvé exiger que le chargement de l'entité et de la modifier, ou la suppression de l'entité, de sorte que la nouvelle peut être inséré. La demande de soins si l'enregistrement existe déjà. Est-il un moyen de contourner cela?
Ne l'Id de la Matière?
Attribué Id
L'objet a un mot-clé attribué l'id et la clé primaire de la table.
Je comprends que SaveOrUpdate() va appeler la méthode Save() ou la méthode Update (), comme approprié en fonction de l'Id. À l'aide d'un id attribué, cela ne fonctionne pas parce que l'id n'est pas une unsaved-value. Cependant une Version ou un champ d'Horodatage peut être utilisé comme un indicateur de la place. En réalité, ce n'est pas pertinente, car cela ne reflète que l'objet dans la mémoire a été associée à un enregistrement dans la base de données; il n'indique pas si le document existe ou pas dans la base de données.
Id Généré
Si l'id attribué était vraiment la cause du problème, je pourrais utiliser un id généré à la place du mot-clé comme clé primaire. Cela permettrait d'éviter le NHibernate Insérer/mettre à Jour la question serait effectivement toujours insérer. Cependant, j'ai encore besoin de prévenir la répétition de mots clés. Avec un index unique sur la colonne de mot clé, il va encore lever une exception pour un duplicata de clé, même si la clé primaire est différente.
Une Autre Approche?
Peut-être que le problème n'est pas vraiment avec NHibernate, mais la manière dont c'est modélisée. Contrairement à d'autres zones de l'application, ce qui est plus centrée sur les données, plutôt de l'objet central. C'est bien que NHibernate le rend facile à lire/écrire et élimine les procédures stockées. Mais le désir d'écrire tout simplement, sans égard aux valeurs existantes ne rentre pas bien avec le modèle d'un objet du modèle d'identité. Est-il une meilleure façon d'aborder cette question?
Lorsque l'objet n'existe pas dans la base de données, j'ai une erreur disant qu'il ne pouvait pas mettre à jour l'objet. Une recherche sur Google activée, les références au fait que les SaveOrUpdate() ne fonctionne pas avec un id attribué.
J'ai mis à jour la question pour expliquer le problème en détail et mon meilleure compréhension de NHibernate
OriginalL'auteur g . | 2008-11-28
Vous devez vous connecter pour publier un commentaire.
Je suis en utilisant
mais FindByExample méthode renvoie tous les objets ressemblent pas à des objets avec l'exacte ID que proposez-vous ? depuis que je l'objet en tant que paramètre je n'ai pas accès à son numéro de champ donc je ne peut pas utiliser
session.get(Object.class(), id);
Tant pis : C'est dans l'utilisation de NHibernate.Critère; espace de noms.
à l'aide de NHibernate; à l'aide de NHibernate.Critère;
OriginalL'auteur ShDev
Généralement, NHibernate peut compter sur le unsaved-value pour déterminer si elle doit insérer ou créer l'entité. Cependant, puisque vous êtes l'attribution de l'IDENTIFIANT, de NHibernate il ressemble à votre entité a déjà été conservées. Par conséquent, vous devez compter sur le versionnement de votre objet à laisser NHibernate sais que c'est un nouvel objet. Voir le lien suivant pour savoir comment la version de votre entité:
http://web.archive.org/web/20090831032934/http://devlicio.us/blogs/mike_nichols/archive/2008/07/29/when-flushing-goes-bad-assigned-ids-in-nhibernate.aspx
href="http://web.archive.org/web/20090831032934/http://devlicio.us/blogs/mike_nichols/archive/2008/07/29/when-flushing-goes-bad-assigned-ids-in-nhibernate.aspx" >web.archive.org/web/20090831032934/http://devlicio.us/blogs/...
Bien trouvé!!! Maintenant, si seulement je pouvais me souvenir de ce que je faisais il y a trois ans que cela m'a intéressé... 😉 je conseille l'édition de ce lien dans la réponse trop bien (ou je peux).
ha ha... je suppose que vous avez attendu tout ce temps pour que le lien soit révélé, et maintenant que vous l'avez, vous pouvez obtenir et d'exécuter cette tâche 🙂 j'ai fait la modification, mais il faut de la "revue par les pairs" pour prendre effet.
OriginalL'auteur pondermatic
Utiliser la session.SaveOrUpdate(objet) de la méthode.
Oui, il peut. Voir le commentaire sur ma réponse.
Il peut être utilisé avec un id attribué si l'objet a une Version ou un champ d'Horodatage. Cela ne résout pas le problème.
OriginalL'auteur gcores
Vous pouvez faire
Si je dois obtenir l'objet de toute façon, je peux la supprimer si elle existe. J'espérais éviter que, bien que.
pourquoi voulez-vous le supprimer, s'il existe? Pourquoi ne pas simplement remplacer? De fusion est en veille prolongée, je ne sais pas à propos de NHibernate. Et à un certain niveau, vous devez vérifier si l'objet existe, soit par l'intermédiaire de l'API hibernate ou manuellement.
SaveOrUpdate() ne peut pas être utilisé lorsque l'entité a une id attribué.
En fait, il peut. C'est précisément l'objet de la saveOrUpdate(). save() ne peut pas être utilisée lorsque vous avez attribué l'id, de mise à jour() ne peut pas être utilisé sans l'un, et saveOrUpdate() contourne le problème.
OriginalL'auteur Elie
Objets de requête mot-clé where = x, prendre FirstOrDefault. Si c'est null, Ajouter un nouvel objet, si elle existe, la mise à jour de l'objet que vous avez obtenu et appel saveOrUpdate.
OriginalL'auteur WholeLifeLearner
appel de mise en veille prolongée.saveOrUpdate() qui vérifie si l'objet est dans la base de données, mettre à jour si cela est, et de l'enregistrer (c'est à dire insérer) si elle ne l'est pas.
Tout à fait correct, mais la ligne du bas est, vous pouvez laisser Hibernate déterminer laquelle des deux méthodes à appeler. À partir d'une mise en œuvre point de vue, c'est juste de la sémantique.
C'est un point important. Si votre session est hors de portée, alors vous obtiendrez probablement un échec....la duplication de la clé primaire comme étant le plus commun.
Cette réponse est tout à fait tort
OriginalL'auteur Elie