Ho un gestore oggetti, che ha proprietà EmailAccount, digitare 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; }
}
e mappatura tra queste classi:
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"));
}
}
poi nel codice ottengo oggetto Manager dal contesto e lo aggiorno
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);
Quindi, come possiamo vedere, EmailAccount non è ottenuto dal contesto ma utilizza un oggetto esterno, ma con Id (PK) lo stesso del contesto!
Quindi, prima di salvare le modifiche, provo ad associare questo oggetto al contesto:
_db.EmailAccounts.Attach(manager.EmailAccount);
ma ho ricevuto un errore:
Salvare o accettare le modifiche non è riuscito perché più di un'entità di tipo "Infrastruttura.Asset.Messages.EmailAccount" hanno lo stesso valore di chiave primaria. Assicurarsi che i valori delle chiavi primarie impostati in modo esplicito siano univoci.
AGGIUNTO
_managerService.GetManager(user.Id)
chiama il seguente metodo:
public Manager GetManager(string aspNetUserId)
{
var manager = _db.Managers
.Include(p => p.EmailAccount)
.Where(p => p.AspNetUser.Id == aspNetUserId)
.FirstOrDefault();
return manager;
}
Perché così, e come lo faccio?
Non è necessario allegarlo nel tuo caso. La seguente riga è sufficiente:
manager.EmailAccount = mapper.Map<EmailAccount>(model.EmailAccount);
Sebbene tu abbia ragione affermando che EmailAccount
non è legato al contesto, l'oggetto manager
è. Assegnando l'account e-mail, verrà tracciato.
Se è necessario collegare un oggetto al contesto o implementare una logica up-sert, vedere questa pagina MSDN .