简体   繁体   中英

Entity Framework Code First adding record error

Ok let me start with my model:

Contact Method Types:

public class ContactMethodType
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    public Guid ContactMethodTypeGUID { get; set; }

    [Required(ErrorMessage = "Please enter a Contact Method Type Name.")]
    public string Name { get; set; }

    [Required(ErrorMessage = "Please enter a brief description.")]
    public string Description { get; set; }

    public bool IsActive { get; set; }

    public virtual ICollection<ContactMethod> ContactMethods { get; set; }

Contact Methods:

public class ContactMethod
{
    [Key]
    [HiddenInput(DisplayValue = false)]
    public Guid ContactMethodGUID { get; set; }

    public virtual ContactMethodType Type { get; set; }

    public string CountryCode { get; set; }

    [Required]
    public string Identifier { get; set; }

    public bool IsPreferred { get; set; }

}

Recipient:

public class Recipient
{
    [Key]
    public Guid RecipientGUID { get; set; }

    [Required(ErrorMessage = "Please enter a Recipient's First Name.")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Please enter a Recipient's Last Name.")]
    public string LastName { get; set; }

    public string Company { get; set; }

    public UserGroup Owner { get; set; }

    public List<ContactMethod> ContactMethods { get; set; }

    public User CreatedBy { get; set; }

    public DateTime CreatedOn { get; set; }

    public User LastModifiedBy { get; set; }

    public DateTime LastModifiedOn { get; set; }

    public bool IsActive { get; set; }

}

I have two Contact Method Types already defined: Email and SMS

Now I am creating a new Recipient, so I add all of the required data to my Recipient Object, and then I call:

context.Recipients.Add(myRecipient);
context.SaveChanges();

What I get is an error that I am tying to add a new ContactMethodType when one already exists. But this is supposed to be a one to many relationship, and I do not want to add a new ContactMethodType, just categorize a new Contact Method(s) for my recipient.

I am not sure when this is happening. Maybe my model is incorrect? Based on what is chosen as the type, I pull that Type object, and set it to the ContactMethod.Type variable. But like I said, instead of just linking it to an existing ContactMethodType, it is trying to re-create it, and since the GUID already exists, I get the error that the record cannot be created because the key (GUID) already exits.

Any ideas?

After discussing this offline with Marek, it boiled down to DbSet<TEntity>.Add(entity) assuming that all entities in the graph being added are new.

From The API docs for Add ...

Begins tracking the given entity, and any other reachable entities that are not already being tracked, in the Added state such that they will be inserted into the database when SaveChanges() is called.

Because this model uses client generated keys, meaning that all entities have a key value assigned before they are given to the context, you can't use any of the "smarter" methods (such as DbSet<TEntity>.Attach(entity) ) that would inspect key values to work out if each entity is new or existing.

After adding the new recipient, you can use call DbSet<TEntity>.Attach(entity) on each existing entity (ie the contact method type). Alternatively, DbContext.Entry(entity).State = EntityState.Unchanged will also let EF know that an entity is already in the database.

You could also look at DbContext.ChangeTracker.TrackGraph(...) , see the API docs for more info.

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