【问题标题】:EF how to Attach entityEF如何附加实体
【发布时间】:2019-01-18 10:18:34
【问题描述】:

我有一个对象管理器,它有属性 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;
    }

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

【问题讨论】:

  • _managerService.GetManager(user.Id) 内部发生了什么?
  • @GertArnold 添加
  • 是的,所以您已经附加了EmailAccount。您应该将model.EmailAccount 的内容复制到附件中,而不是附加映射的帐户。
  • @GertArnold,我的班级可以有几十个参数,我不想手动复制每个字段。没有手动复制的任何方法?

标签: c# entity-framework entity-framework-6 dbcontext


【解决方案1】:

在您的情况下无需附加它。以下行就足够了:

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

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

如果您确实需要将对象附加到上下文,或者想要实现一些 up-sert 逻辑,请参阅MSDN page

【讨论】:

  • 然后我收到一个错误:“来自‘Manager_EmailAccount’关联集的关系处于‘已删除’状态。鉴于多重约束,相应的‘Manager_EmailAccount_Target’也必须处于‘已删除’状态。” .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多