我有一个对象管理器,其属性为EmailAccount,键入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; }
}


以及这些类之间的映射:

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"));
    }
}


然后在代码中,我从上下文中获取对象管理器并对其进行更新

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);


因此,正如我们所看到的,EmailAccount不是从上下文中获取的,而是使用一个外部对象,但其ID(PK)与上下文中的相同!

然后,在保存更改之前,我尝试将此对象附加到上下文:

_db.EmailAccounts.Attach(manager.EmailAccount);


但我得到一个错误:


  保存或接受更改失败,因为存在多个实体
  类型“ Infrastructure.Asset.Messages.EmailAccount”具有相同的
  主键值。确保明确设置的主键值为
  独特。


添加

_managerService.GetManager(user.Id)调用以下方法:

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


为什么这样,我该怎么做?

最佳答案

您无需附加它。以下行就足够了:

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


尽管通过声明EmailAccount未绑定到上下文是正确的,但manager对象是正确的。通过分配电子邮件帐户,将对其进行跟踪。

如果确实需要将对象附加到上下文,或者要实现一些向上插入逻辑,请参见此MSDN page

关于c# - EF如何附加实体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51792609/

10-09 19:41