简体   繁体   中英

Adding collection of owned objects

I've got a domain model with collection of owned types. When I try to add more than one object in the ownedtyped collection? I get an exception:

System.InvalidOperationException : 'The instance of entity type 'ChildItem' cannot be tracked because another instance with the key value '{NameId: -2147482647, Id: 0}' is already being tracked. When replacing owned entities modify the properties without changing the instance or detach the previous owned entity entry first.'

How can it be solved?

UPDATED

My domain classes:

public class Parent
    {
        public int Id { get; set; }
        public Child Name { get; set; }
        public Child ShortName { get; set; }
    }

    public class Child
    {
        public List<ChildItem> Items { get; set; }
    }

    public class ChildItem
    {
        public string Text { get; set; }
        public string Language { get; set; }
    }

My DbContext:

public class ApplicationContext : DbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Parent>()
                .OwnsOne(c => c.Name, d =>
                {
                    d.OwnsMany(c => c.Items, a =>
                    {
                        a.HasForeignKey("NameId");
                        a.Property<int>("Id");
                        a.HasKey("NameId", "Id");
                        a.ToTable("ParentNameItems");
                    })
                    .ToTable("ParentName");
                })
                .ToTable("Parent");

                modelBuilder.Entity<Parent>()
                .OwnsOne(c => c.ShortName, d =>
                {
                    d.OwnsMany(c => c.Items, a =>
                    {
                        a.HasForeignKey("NameId");
                        a.Property<int>("Id");
                        a.HasKey("NameId", "Id");
                        a.ToTable("ParentShortNameItems");
                    })
                    .ToTable("ParentShortName");
                })
                .ToTable("Parent");
        }
    }

Usage:

static void Main(string[] args)
        {
            var context = new ApplicationContext();

            var parent = new Parent()
            {
                Name = new Child()
                {
                    Items = new List<ChildItem>()
                    {
                        new ChildItem() { Text = "First value", Language = "en-en"},
                        new ChildItem() { Text = "Second value", Language = "en-en"}
                    }
                },
                ShortName = new Child()
                {
                    Items = new List<ChildItem>()
                    {
                        new ChildItem() { Text = "First short value", Language = "en-en"},
                        new ChildItem() { Text = "Second short value", Language = "en-en"}
                    }
                }
            };

            context.Set<Parent>().Add(parent);

            context.SaveChanges();
        }

Well, first of all you classes don't make sense. If anything it should be

public class Parent
{
    public int Id { get; set; }
    public List<Child> Children { get; set; }
}

a parent should have many children (or none possibly, empty list maybe?). What about the child's name and id, doesn't he have one of each ? also maybe a ParentId maybe something like

public class Child
{
    public virtual List<ChildItem> Items { get; set; } //why virtual? you planning to inherit?
    public string Name {get; set; }
    public int Id {get; set; }
    public int ParentId {get; set; }
}

That looks a little better, I should think. The database should have matching tables. and let's be honest EF (Entity Framework) auto create will do 99% of the work for you, so please use it.

Problem is solved. It was in line

a.HasKey("NameId", "Id");

in OnModelCreating method. I used an example where was written abount configuring Collections of owned types.

After deleting "NameId" field from Key definition

a.HasKey("Id");

everything works fine now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM