Question

I have an object Manager, which has property EmailAccount, type EmailAccount:

public class Manager 
{
    .....
    public virtual EmailAccount EmailAccount { get; set; }
}

public partial class EmailAccount : BaseEntity
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string DisplayName { get; set; }
    ....
    public virtual Manager Manager { get; set; }
}

and mapping between these classes:

public class ManagerMap : EntityTypeConfiguration<Manager>
{
    public ManagerMap()
    {
        this.ToTable("Manager");
        this.HasKey(dp => dp.Id);
        this.Property(p => p.FirstName).IsRequired().HasMaxLength(250);
        this.Property(p => p.LastName).IsRequired().HasMaxLength(250);
        this.Property(p => p.Nickname).HasMaxLength(250);

        this.HasOptional(c => c.EmailAccount)
            .WithRequired(a => a.Manager)
            .Map(m => m.MapKey("ManagerId"));
    }
}

then in code I get object Manager from context and update it

var manager = _managerService.GetManager(user.Id);
manager.FirstName = model.FirstName;
manager.LastName = model.LastName;
manager.Nickname = model.Nickname;
manager.EmailAccount = mapper.Map<EmailAccount>(model.EmailAccount);

So, as we can see, EmailAccount is not gotten from context but uses an external object, but with Id (PK) the same as in context!

Then, before save changes, I try to attach this object to context:

_db.EmailAccounts.Attach(manager.EmailAccount);

but I got an error:

Saving or accepting changes failed because more than one entity of type 'Infrastructure.Asset.Messages.EmailAccount' have the same primary key value. Ensure that explicitly set primary key values are unique.

ADDED

_managerService.GetManager(user.Id) calls the following method:

    public Manager GetManager(string aspNetUserId)
    {
        var manager = _db.Managers
            .Include(p => p.EmailAccount)
            .Where(p => p.AspNetUser.Id == aspNetUserId)
            .FirstOrDefault();
        return manager;
    }

Why so, and how do I do it?

1
2
8/11/2018 11:01:28 AM

Popular Answer

There is no need to attach it in your case. The following line is sufficient:

manager.EmailAccount = mapper.Map<EmailAccount>(model.EmailAccount);

Although, you are correct by stating that EmailAccount isn't bound to the context, the manager object is. By assigning the email account, it will be tracked.

If you do need to attach an object to the context, or want to implement some up-sert logic, see this MSDN page.

0
8/10/2018 7:26:25 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow