Para Kan
Para Kan

Reputation: 121

Entity Framework - adding an existing entity to one to one relationship in seed method

My Domain Classes:

public class Address
{
    [Key]
    public virtual string AddressId { get; set; }

    public virtual Site Site { get; set; }
}

public class Site
{
    [Key]
    public virtual int SiteId { get; set; }

    public virtual Address Address { get; set; }
}

Mapping using Fluent API:

public class SiteMappings : EntityTypeConfiguration<Site>
{
    public SiteMappings()
    {
        HasRequired(s => s.Address)
        .WithOptional(a => a.Site)
        .Map(s => s.MapKey("AddressId"))
        .WillCascadeOnDelete(false);
    }
}

Seed Method:

var addresses = new List<Address>
{
    new Address { AddressId = "1" }
};
addresses.ForEach(s => context.Addresses.AddOrUpdate(p => p.AddressId, s));

var sites = new List<Site>
{
    new Site { SiteId = 1, Address = addresses.Single(s => s.AddressId.Equals("1"))}
};
sites.ForEach(s => context.Sites.AddOrUpdate(p => p.SiteId, s));

Error:

Violation of PRIMARY KEY constraint 'PK_dbo.Addresses'. Cannot insert duplicate key in object 'dbo.Addresses'. The duplicate key value is (1)

It seems to be when I try to add a new "site", new "address" also get inserted. How to avoid this? How to insert an existing "address" in DBcontext I just added before. I'm new to Entity Framework and really appreciate your help. Thanks in advance!

Upvotes: 3

Views: 2781

Answers (2)

Para Kan
Para Kan

Reputation: 121

I was able to solve this issue by inserting an "Address" managed by the current context.

new Site { SiteId = 1, Address = context.Addresses.FirstOrDefault(a => a.AddressId.Equals("1"))}

Below code will utilize an existing "Address" managed by the current context instead of trying to insert a new "Address".

context.Addresses.FirstOrDefault(a => a.AddressId.Equals("1"))}

Upvotes: 1

Liviu Mandras
Liviu Mandras

Reputation: 6627

After you assign the address to the site instance, use this for each address instance:

context.Entry(existingAddress).State = EntityState.Unchanged;

This will set the state of the addresses as Unchanged instead of Added and EF will not try to add them a second time.

Also try calling context.SaveChanges() after the ForEach where you add the addresses.

Upvotes: 2

Related Questions