Ajout d'éléments à une collection à l'aide d'Entity Framework

Je suis en train de suivre le DDD modèle de Référentiel avec Entity Framework 4. Mais je vais avoir des problèmes pour enregistrer les modifications apportées à la collection de propriétés de mon agrégation des racines. Envisager de mes classes ci-dessous. L'élément est mon agrégation racine qui contient une collection de Point entités.

public class Item
{
    public int ItemId { get; set; }
    public string Name { get; set; }
    public ICollection<SubItem> SubItems { get; private set; }

    public Item()
    {
        this.SubItems = new HashSet<SubItem>();
    }
}

public class SubItem
{
    public int ItemId { get; set; }
    public int SubItemId { get; set; }
    public string Name { get; set; }
}

Ensuite, j'ai défini un référentiel d'interface pour mon agrégation de classe racine

public interface IItemRespository
{
    Item Get(int id);
    void Add(Item i);
    void Save(Item i);
}

Maintenant voici mon DbContext classe qui met en place le EF de la cartographie.

public class ItemContext : System.Data.Entity.DbContext
{
    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Item>().HasKey(i => i.ItemId);
        modelBuilder.Entity<Item>().Property(i => i.Name);

        modelBuilder.Entity<Item>().HasMany(i => i.SubItems)
            .WithRequired()
            .HasForeignKey(si => si.ItemId);

        modelBuilder.Entity<SubItem>().HasKey(i => i.SubItemId);
        modelBuilder.Entity<SubItem>().Property(i => i.Name);
    }
}

Enfin, voici ma mise en œuvre de IRepository à l'aide de la DBContext

public class Repository : IItemRespository
{
    public void Save(Item i)
    {
        using (var context = new ItemContext())
        {
            context.Set<Item>().Attach(i);
            context.SaveChanges();
        }
    }

    public Item Get(int id)
    {
        using (var context = new ItemContext())
        {
            var result = (from x in context.Set<Item>() where x.ItemId == id select x).FirstOrDefault();
            return result;
        }
    }

    public void Add(Item i)
    {
        using (var context = new ItemContext())
        {
            context.Set<Item>().Add(i);
            context.SaveChanges();
        }
    }
}

Le code suivant crée un nouvel Élément, il ajoute à l'référentiel, ajoute de nouveaux Éléments, puis enregistre les modifications.

IItemRespository repo = new Repository();

//Create a new Item
Item parent = new Item() { Name = "Parent" };
repo.Add(parent);

//A long period of time may pass .. . .

//later add sub items
parent.SubItems.Add(new SubItem() { Name = "Child 1" });
parent.SubItems.Add(new SubItem() { Name = "Child 2" });   
parent.SubItems.Add(new SubItem() { Name = "Child 3" });

//save the added sub items
repo.Save(parent);

- Je obtenir de l'exception suivante lorsque la méthode Save() tente de joindre l'élément du contexte.

Une contrainte d'intégrité référentielle violation a eu lieu: La propriété
les valeurs qui définissent les contraintes référentielles ne sont pas compatibles
entre le principal et les objets qui en dépendent dans la relation.

J'ai réalisé que je suis en création d'un nouveau contexte pour chaque méthode dans le référentiel. Cela est intentionnel. Une longue période de temps peut se passer entre le moment où un Élément est ajouté, et puis plus tard, édité, et je ne veux pas garder le contexte ou la connexion de base de données ouverte pour le moment.

Maintenant, si j'ai fixer la newItem pour le deuxième contexte avant d'ajouter les sous-éléments, comme dans le code ci-dessous, il fonctionne.

//Create a new item
Item newItem = new Item() { Name = "Parent" };

using (ItemContext context1 = new ItemContext())
{
    //Create a new aggrgate
    context1.Set<Item>().Add(newItem);
    context1.SaveChanges();
}

//Long period of time may pass

using (ItemContext context2 = new ItemContext())
{
    context2.Set<Item>().Attach(newItem);

    newItem.Name = "Edited Name";
    newItem.SubItems.Add(new SubItem() { Name = "Child 1" });
    newItem.SubItems.Add(new SubItem() { Name = "Child 2" });
    newItem.SubItems.Add(new SubItem() { Name = "Child 3" });

    context2.SaveChanges();
}

Cependant, si je veux être fidèle au modèle de référentiel le code qui modifie Élément ne sais rien à propos de la façon dont le référentiel de travaux ou à la ItemContext classe. Il doit simplement être capable de faire des changements pour un total de racine entité, puis enregistrer ces changements par le biais d'un référentiel méthode Save ().

Alors, comment puis-je modifier ma méthode Save() de sorte que les modifications apportées à l'Élément.Les points sont enregistrés correctement?

source d'informationauteur Eric Anastas