2009-08-14 9 views
1

Existe-t-il un ModelBinder pré-construit que je peux utiliser avec LINQ pour obtenir un objet d'un DataContext et le mettre à jour sur un post HTTP?ASP.NET MVC, LINQ et ModelBinders

Par exemple, actuellement j'ai ce bloc de code:

[AcceptVerbs (HttpVerbs.Post)] 
public ActionResult Edit (Project project) 
{ 
    var projectService = Factory.GetService<IProjectService>(); 
    project = projectService.GetProject (project.ProjectId); 

    UpdateModel<Project> (project); 

    if (!ModelState.IsValid) 
     return View (project); 

    project = projectService.SaveProject (project); 

    return RedirectToAction ("Details", new { id = project.ProjectId }); 
} 

(IProjectService TERMINE appels à un contexte de données LINQ)

Afin de réaliser effectivement la mise à jour la base de données via le LINQ contexte de données, j'ai besoin d'obtenir l'instance de projet à nouveau, puis mettre à jour cette instance. Toute tentative de sauvegarde de l'instance du projet sans l'avoir obtenue du contexte de données n'a pour conséquence aucune réécriture dans la base de données. Je suppose que le contexte de données LINQ ne sait rien de l'objet. Il ne fait rien. avec ça.

L'utilisation de la méthode Attach sur la classe de la table Projects ne fonctionne pas non plus btw, elle déclenche une exception.

Répondre

3

Vous devriez regarder la mise en œuvre (nouvelle BSD) Mike Hadlow SutekiShop.

Vous y trouverez un DataBindAttribute et un BindUsingAttribute qui, si je comprends bien, font exactement ce que vous voulez faire. Remarquez comment la propriété DataBindAttribute.Fetch est utilisée pour redéfinir les données entrantes, ou non (à partir d'un HttpPost) vers une entité LINQ. J'ai suivi ce modèle pour l'un de mes projets en utilisant ASP.NET MVC et LINQ-To-SQL. Cela fonctionne magnifiquement.

est ici la source: http://www.google.com/codesearch?hl=en&lr=&q=DataBind+package%3Ahttp%3A%2F%2Fsutekishop.googlecode.com&sbtn=Search

+0

C'est tout à fait, merci Robert! – Kieron

+0

SutekiShop a beaucoup de code génial, content que cela fonctionne pour vous. –

0

Je pense que le projet que vous transmettez à la méthode est celui que vous voulez exécuter avec UpdateModel, n'est-ce pas?

Sinon, vous essayez de mettre à jour avec des valeurs préexistantes et non des nouvelles.

Juste une pensée,

Dan

code découpé ci-dessous

[AcceptVerbs (HttpVerbs.Post)] 
public ActionResult Edit (Project project) 

    UpdateModel<Project> (project); 

    if (!ModelState.IsValid) 
      return View (project); 

    var projectService = Factory.GetService<IProjectService>(); 

    project = projectService.SaveProject (project); 

    return RedirectToAction ("Details", new { id = project.ProjectId }); 
} 
+0

projet et non projectToUpdate est celui qui utilise le ModelBinder –

+0

Le problème, que je n'explique très bien, est que l'instance du projet qui vient du liant est très bien, à part Du fait qu'il a été construit par le MVC FW quelque part sur la ligne, et non récupéré à partir du DataContext. Lors de la mise à jour de cette instance, le DataContext ne fait pratiquement rien, probablement parce qu'il ne sait rien de cet objet. – Kieron

0

Vous devez récupérer le projet initial comme vous le faites alors mettre à jour avec les propriétés qui ont changé dans le projet mettre à jour puis soumettre la demande de mise à jour.

EDIT

Essayez ce code, j'ai trouvé:

public static void CloneProperties(this object origin, ref object destination) 
{ 
    if (destination == null) throw new ArgumentNullException("destination", "Destination object must first be instantiated."); 
    foreach (var destinationProperty in destination.GetType().GetProperties()) 
    { 
     if (origin != null && destinationProperty.CanWrite) 
     { 
      origin.GetType().GetProperties().Where(x => x.CanRead && (x.Name == destinationProperty.Name && x.PropertyType == destinationProperty.PropertyType)) .ToList() .ForEach(x => destinationProperty.SetValue(destination, x.GetValue(origin, null), null)); 
     } 
    } 
} 
+0

Ouais, c'est ce que je fais - ce que je voudrais, c'est peut-être de créer un ModelBinder qui ferait ça pour moi ... simplement pour ne pas avoir à faire un get dans les contrôleurs à chaque fois. Si je change pour un autre ORM plus tard, je ferai des get supplémentaires qui ne sont pas nécessaires. Tout ce que je devrais faire avec le classeur est d'enlever/restaurer l'original. Des pensées? – Kieron

+0

http://msdn.microsoft.com/en-us/library/bb896248.aspx – Gregoire

+0

@Gregorie, j'ai essayé d'utiliser la méthode Attach il y a un certain temps, mais il y a une exception à propos de l'objet qui existe déjà (je suppose que c'est basé sur la vérification sur c'est PK). – Kieron