10 votes

Comment sauvegarder un modèle qui contient des données existantes ainsi que de nouvelles données ?

Actuellement, j'ai un modèle qui contient des données existantes ainsi que de nouvelles données.

Voici un exemple de mon modèle :

 public class NameDetails
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }

Voici les fausses données qu'il contient actuellement :

  List Names = new List{

                new  NameDetails{Id = 1, Name = "Name 1"},
                new NameDetails{Id = 2 , Name = "Name 2"},
            };

Supposons maintenant que je doive enregistrer ces données dans une base de données... J'ai déjà l'id = 1 dans la table, donc cela devrait être une mise à jour, tandis que l'id = 2 devrait être un ajout... comment puis-je faire cela ?

Auparavant, lorsque j'écrivais des enregistrements en utilisant un dépôt, je faisais soit un ajout soit une modification

Ajout comme ceci :

 context.NameDetails.Add(NameDetails); 
    context.SaveChanges(); 

ou

Modification comme ceci :

var recordToUpdate = context.NameDetails.FirstOrDefault(x => x.Id== 1);
recordToUpdate.Name = "New name";
context.SaveChanges();

cela signifie-t-il que je dois parcourir ma liste et déterminer ce qui est nouveau et ce qui ne l'est pas.. ou existe-t-il une autre façon ?

2voto

ken2k Points 24640

Vous pourriez utiliser certaines conventions qui fonctionnent bien avec Entity Framework.

Par exemple, si vous utilisez IDENTITY(1,1) sur votre base de données (afin qu'elle génère automatiquement des identifiants pour vos lignes insérées), votre propriété d'entité devrait utiliser StoreGeneratedPattern défini comme Identity (dans le cas d'une approche de modèle en premier), et votre propriété Id avec une valeur 0 signifie qu'elle n'a pas encore été ajoutée à la base de données.

Ensuite, vous pouvez facilement décider ce qu'il faut ajouter et ce qu'il faut mettre à jour. Voici un exemple de code pseudo (non testé) :

foreach (var entity in entities)
{
    if (entity.Id == 0)
    {
        // Ajoute au contexte pour une insertion en base de données
        context.Entities.Add(entity);
    }
    else
    {
        // Met à jour l'entité existante (propriété par propriété dans cet exemple, vous pourriez mettre à jour
        // toutes les propriétés en une seule fois si vous le souhaitez)
        var dbEntity = context.Entities.Single(z => z.Id == entity.Id);
        dbEntity.Prop1 = entity.Prop1;
        // etc...
    }
}

context.SaveChanges();

1voto

Steve Ruble Points 3735

Uniquement EF5+ :

Si vous avez un moyen de détecter si un élément est nouveau (Id == 0 est bon, comme dans la réponse de ken2k), vous pouvez faire cela pour éviter de devoir mapper les choses :

foreach(var entity in entities)
{
    context.NameDetails.Attach(entity);
    context.Entry(entity).State = IsNewEntity(entity) 
                                  ? EntityState.Added
                                  : EntityState.Modified;
}

Cela indiquera à EntityFramework de créer des INSERT pour les nouvelles entités et des UPDATE pour les anciennes entités.

0voto

karaxuna Points 11303

Essayez ceci :

var nameIds = Noms.Select(n => n.Id);

var recordsToUpdate = context.DétailsNom.Where(x => nameIds.Contains(x.Id));

0voto

Simon Belanger Points 5480

Entity Framework ne fonctionne pas très bien dans ce genre de situations. Cela devrait vous rapprocher de ce que vous recherchez :

public class NameDetails
{
    public int Id {get;set;}
    public string Name {get;set;}
}

List Names = new List
    {
        new  NameDetails{Id = 1, Name = "Name 1"},
        new NameDetails{Id = 2 , Name = "Name 2"},
    };

var toFetch = Names.Select(n => n.Id).ToArray();
var association = context.NameDetails
                         .Where(n => toFetch.Contains(n.Id))
                         .ToDictionary(n => n.Id);

foreach(var name in Names)
{
    NameDetails existing;
    if(association.TryGetValue(name.Id, out existing))
    {
        // It exists, map the properties in name to existing
    }
    else
    {
        // It's new, perform some logic and add it to the context
        context.NameDetails.Add(name);
    }
}

context.SaveChanges()

Alternativement, vous pourriez essayer de contourner la méthode AddOrUpdate des migrations Entity Framework qui effectue une mise à jour ou insertion :

// Vous avez besoin d'importer le namespace System.Data.Entity.Migrations
context.NameDetails.AddOrUpdate(names.ToArray());
context.SaveChanges();

Je n'ai pas essayé cela, mais cela devrait fonctionner, à moins qu'il y ait une logique supplémentaire dans le AddOrUpdate qui m'échappe.

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