4 votes

Puis-je affecter un objet à un objet d'entité ?

J'utilise ASP.NET MVC4 Web API, et mon action PUT, je veux faire quelque chose comme ça :

public void Put(string id, [FromBody]Foo value)
{
    var context = new FooBarEntities();
    Foo existingFoo = context.Foos.Where(x => x.Id == id).First();
    existingFoo = value;
    context.SaveChanges();
}

Mais les changements dans la Foo value ne sont pas sauvegardés. Si je devais faire chaque propriété, cela fonctionnerait comme suit :

public void Put(string id, [FromBody]Foo value)
{
    var context = new FooBarEntities();
    Foo existingFoo = context.Foos.Where(x => x.Id == id).First();
    existingFoo.Prop1 = value.Prop1;
    existingFoo.Prop2 = value.Prop2;
    context.SaveChanges();
}

Existe-t-il un moyen de mettre à jour chaque propriété en assignant simplement l'objet ?

2voto

Michael Haren Points 42641

Cela ne va certainement pas fonctionner :

Foo existingFoo = context.Foos.Where(x => x.Id == id).First();
existingFoo = value;

Vous cherchez une référence, puis vous la remplacez immédiatement par quelque chose d'entièrement différent.

Je pense que vous voulez attach votre value dans le contexte, puis sauvegarder. Quelque chose de plus comme ceci pourrait le faire pour vous :

context.Foos.AddObject(value);
context.ObjectStateManager.ChangeObjectState(value, System.Data.EntityState.Modified);
context.SaveChanges();

Il n'est pas nécessaire de charger d'abord l'objet à mettre à jour, ce qui est appréciable. Si cela ne suffit pas, le fait de savoir que cela s'appelle quelque chose comme disconnected La mise à jour pourrait vous aider dans vos recherches futures.

Si vous avez déjà en main l'objet à mettre à jour, ainsi que la nouvelle copie, je ne connais rien de propre qui les fusionne pour vous.


Une autre voie Je l'ai fait avant ressemble davantage à ceci, ce qui peut sembler moins compliqué :

var entity = context.Entry(value);
entity.State = EntityState.Modified;
context.SaveChanges();

Ou de manière plus concise :

context.Entry(value).State = EntityState.Modified;
context.SaveChanges();

Je ne me souviens pas si c'est une fonction intégrée ou non.

1voto

ikwillem Points 606

Réponse courte : Non.

Mais il y a de nombreuses façons d'obtenir le même résultat, j'ai écrit une fois ce code qui utilise la réflexion pour copier toutes les propriétés de vos objets :

    public void CopyLinqObject(object obj_source, object obj_dest)
    {
        Type t_source = obj_source.GetType();
        PropertyInfo[] p_source = t_source.GetProperties();

        Type t_dest = obj_dest.GetType();
        PropertyInfo[] p_dest = t_dest.GetProperties();

        foreach (PropertyInfo ps in p_source)
        {
            foreach (PropertyInfo pd in p_dest)
            {
                if (ps.Name == pd.Name)
                {
                    if (ps.PropertyType == pd.PropertyType)
                    {
                        if (ps.PropertyType.IsSerializable)
                        {
                            pd.SetValue(obj_dest, ps.GetValue(obj_source, null), null);
                        }
                    }
                    else
                    {
                        if (ps.PropertyType.BaseType == pd.PropertyType.BaseType)
                        {
                            if (ps.PropertyType.IsSerializable)
                            {
                                if (ps.GetValue(obj_source, null) != null)
                                {
                                    try
                                    {
                                        pd.SetValue(obj_dest, ps.GetValue(obj_source, null), null);
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

0voto

alex Points 7073

Vous ne pouvez pas "assigner" les propriétés d'un objet à un autre de cette manière. Votre code ne fait que modifier la valeur de la variable existingFoo.

Vous pouvez soit mettre en œuvre votre propre code de copie de propriété, soit jeter un coup d'œil à l'attachement d'une classe à un contexte de données existant.

0voto

gdoron Points 61066

Existe-t-il un moyen de mettre à jour chaque propriété en assignant simplement l'objet ?

Non EF suit les changements avec les propriétés, ils implémentent les classes inotifypropertychanged Lorsque vous changez simplement la référence de la variable, vous ne modifiez pas les propriétés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X