2012-01-08 1 views
0

J'utilise subsonic pour accéder à ma base de données dans une application mvc. Lors de la tentative de mise à jour d'un enregistrement à l'aide de la liaison de modèle mvc, l'enregistrement ne se met pas à jour car aucune des colonnes n'est marquée comme étant sale.Comment utiliser la mise à jour Subsonic en utilisant la liaison de modèle mvc?

J'ai essayé de marquer manuellement toutes les colonnes comme étant corrompues en modifiant le code subsonique, mais parfois je ne veux que mettre à jour certaines propriétés, donc je ne veux pas les marquer comme sales.

Quelle est la meilleure façon de faire cela?

ceci est mon action:

 [HttpPost] 
     public ActionResult Update(mapping m) 
     { 
      m.SetIsNew(false); 
      m.Update(true); // here i tweaked the subsonic code passing true sets all the columns to be dirty and updates the record even though isLoaded=false 
      return RedirectToAction("New"); 
     } 

c'est comment je peaufiné le code subsonique:

public void Update(IDataProvider provider, Boolean forceUpdate){ 
      if(this._dirtyColumns.Count>0 || forceUpdate){ 
       if(forceUpdate) 
        this._dirtyColumns = this.Columns.ToList(); 
       _repo.Update(this,provider); 
       _dirtyColumns.Clear();  
      } 
      OnSaved(); 
     } 

EDIT:

J'ai essayé ce code pour voir où le problème mensonges:

var m = new mapping { ID = 2, Name = "33" }; 
m.SetIsNew(false); 
m.Save(); 

Cela aussi ne fonctionne pas les colonnes ne sont pas mis à sale. Il semble que lorsque l'initialiseur d'un objet est utilisé, les setters ne sont pas appelés, donc les colonnes ne sont pas mises à dirty.

Je suppose que la liaison de modèle mvc.net par défaut fonctionne de cette façon et c'est pourquoi l'enregistrement n'est pas mis à jour.

Modifier 2

Ma première édition est erronée @ dyork12 souligné. Subsonic utilise un indicateur 'isLoaded', lorsqu'il est défini sur false, les propriétés de paramètre ne les définissent pas comme étant sales. ceci est utilisé par subsonic lors du chargement d'un enregistrement, pour s'assurer que la définition des propriétés pendant le chargement ne soit pas aussi sale.

Mais ma question demeure quelle est la meilleure solution pour éditer un objet subsonique à partir d'une vue mvc.net en utilisant la liaison de modèle automatique.

+0

À votre avis, est-ce que vous liez l'objet généré par SubSonic ou utilisez un ViewModel? Avez-vous vu cette? http://stackoverflow.com/questions/5491733/subsonic-and-automapper-dirtycolumns-collection-is-empty-therefore-cant-updat – DaveHogan

+0

Pourquoi ne sont-ils pas marqués sales? Ce fragment de code provient d'ActiveRecord, et si vous liez aux propriétés de la colonne, tout devrait fonctionner correctement. Que faites-vous différemment? Plus de code s'il vous plaît. –

+0

@ dyork12: j'ai répondu dans le 'edit'. – Daniel

Répondre

0

Le problème d'origine (comme maintenant compris) est que MVC charge en quelque sorte des lignes et crée des objets DAL pour eux sans réglage l'indicateur isLoaded, puis tous les appels aux setters ne sont pas ajoutés dans la liste dirtyColumns. Vous devez trouver un moyen de définir isLoaded après le chargement de l'enregistrement et la création de l'objet DAL, avant que les setters ne soient appelés.

Désolé, je ne connais pas suffisamment MVC pour vous aider, et vous n'avez inclus aucun code pour cette partie. Je m'attendrais à insérer une sorte d'événement, ou hériter de quelque chose, ou modifier un modèle, ou quelque chose. Dès que vous trouvez un moyen de définir isLoaded, vous allez résoudre le problème. J'espère.

+0

Merci, je suppose que c'est la voie à suivre. mais à mon avis, la façon dont le drapeau isLoaded fonctionne n'est pas intuitive, il ne devrait pas être là. S'il y a un problème lorsque subsonic charge l'enregistrement à partir de la base de données, il doit définir un indicateur de chargement, puis le désinstaller une fois qu'il est fait, cela ne devrait pas être vu par les utilisateurs de subsonic. – Daniel

+0

C'est un modèle commun d'avoir un drapeau chargé et un drapeau sale. L'indicateur chargé indique qu'une ligne a été extraite de la base de données; le drapeau sale dit qu'il a été modifié; ensemble, ils couvrent toutes les combinaisons. Si vous souhaitez charger/enregistrer des lignes sans utiliser l'API fournie, il est de votre responsabilité de comprendre et de gérer ces indicateurs selon vos besoins. Ils doivent être réglés correctement pour que Save/Update fonctionne. –

1

Je vais prendre un punt et dire que je pense que la réponse est que _isLoaded est faux. Sans voir beaucoup plus de code, je ne peux pas vous dire pourquoi.

Si vous créez un nouvel enregistrement, _isNew est vrai et _isLoaded est faux. Lorsque vous enregistrez, il fait un INSERT et ignore les colonnes sales.

Si vous chargez un enregistrement existant _IsNew est faux et _isLoaded est true. Lorsque vous enregistrez, il effectue une mise à jour et ne met à jour que les colonnes endommagées.

Votre fragment de code définit _isNew false mais ne définit pas _isLoaded true. Les colonnes ne sont pas marquées sales, donc rien ne sauve. C'est facile à voir en lisant le code généré par ActiveRecord.

[BTW Vous avez tort setters - ils sont appelés par un initialiseur d'objet.]

+0

Merci. J'ai édité ma question pour corriger mon erreur. Le code que j'ai posté est tout le code 'mapping' est l'objet subsonique qu'il est chargé par la liaison de modèle automatique de mvc.net et puis je mets à jour. La définition de isLoaded sur true n'aide pas car les propriétés ne sont pas sales. est-il possible que je puisse utiliser la liaison automatique? – Daniel

Questions connexes