How do I add an object to a Collecting and recording all together?

Feb 27, 2014 at 2:12 AM
Example
public class Invoice : Repository.Pattern.Infrastructure.Entity
{
    public int InvoiceID { get; set; }
    public string Number { get; set; }
    public virtual ICollection<InvoiceItem> Items { get; set; }
}

public class InvoiceItem : Repository.Pattern.Infrastructure.Entity
{
    public int InvoiceID { get; set; }
    public virtual Invoice Invoice { get; set; }
    public int Position { get; set; }
}
public class InvoiceMap : EntityTypeConfiguration<Invoice>
{
    public InvoiceMap()
    {
        this.HasKey(t => t.InvoiceID);
        this.Property(t => t.Number).IsRequired();
        this.ToTable("Invoice");
    }
}
public class InvoiceItemMap : EntityTypeConfiguration<InvoiceItem>
{
    public InvoiceItemMap()
    {
        this.HasKey(t => t.InvoiceID);
        this.Property(t => t.Position).IsRequired();
        this.ToTable("InvoiceItem");
        this.HasRequired(t => t.Invoice).WithMany(t => t.Items).WillCascadeOnDelete(false);
    }
}
public class MyContext : DataContext
{
    public MyContext() :base("MyContext"){}
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new InvoiceMap());
        modelBuilder.Configurations.Add(new InvoiceItemMap());
    }
}


When run this code, dont work, throw a exception

using (IDataContextAsync context = new MyContext())
        using (IUnitOfWork unitOfWork = new UnitOfWork(context))
        { 
            var item1 = new InvoiceItem
            {
                Position = 1
            };

            var invoice = new Invoice
            {
                Number = "1",
                Items = new List<InvoiceItem>() { item1 }
            };

            item1.Invoice = invoice;

            try
            {
                unitOfWork.Repository<Invoice>().Insert(invoice);
                unitOfWork.SaveChanges();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Console.ReadLine();
            }

        }


This framework is fantastic!!!

Thanks, Diego.
Coordinator
Feb 27, 2014 at 4:12 PM
Hi Diego,

You need to make sure you set each of the IObjectStates in your graph e.g. Invoice and all loop through your InvoiceItems and set each of their IObjectState to right states, by default everything's state is Unchanged.

Then you need to use one of these methods from IRepostiory (depending if your doing an insert or update)[
    void InsertGraph(TEntity entity);

    void UpdateGraph(TEntity entity);
Marked as answer by lelong37 on 3/31/2014 at 10:25 PM
Apr 14, 2014 at 4:24 PM
lelong37 wrote:
Hi Diego,

You need to make sure you set each of the IObjectStates in your graph e.g. Invoice and all loop through your InvoiceItems and set each of their IObjectState to right states, by default everything's state is Unchanged.

Then you need to use one of these methods from IRepostiory (depending if your doing an insert or update)[
    void InsertGraph(TEntity entity);

    void UpdateGraph(TEntity entity);
Hi there, @lelong37 you mention UpdateGraph(TEntity entity), but there is no such method, any sample on how to update many to many relationships?
May 10, 2014 at 11:14 AM
Edited May 10, 2014 at 6:49 PM
This was exactly the issue I brought up a few months ago which caused me a great deal of confusion. This is because this framework is designed for n-tier applications where entities are detached from the context so having to explicitly set state is needed so when the entities are attached back to the context, their state can be synced so EF knows what to perform (CRUD)...

I offered several solutions, one being a recursive/reflective solution to set state in graphs without having to explicitly set it. Check out my post on that for details.