【问题标题】:Add Detached object to EF 6将分离的对象添加到 EF 6
【发布时间】:2015-06-20 15:17:33
【问题描述】:

我有一个具有许多不同属性的分离对象。其中一些属性需要在某些时候“附加”,以便 EF 不会尝试将它们插入数据库。

public partial class Load 
{
    public virtual int Id {get;set;}

    [Required]
    public virtual int CustomerId { get; set; }

    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }

    [Required]
    public virtual long CreatedByApplicationUserId { get; set; }

    [ForeignKey("CreatedByApplicationUserId")]
    public virtual ApplicationUser CreatedByApplicationUser { get; set; }

    public virtual long? ModifiedByApplicationUserId { get; set; }

    [ForeignKey("ModifiedByApplicationUserId")]
    public virtual ApplicationUser ModifiedByApplicationUser { get; set; }

    public virtual long? CoveredByApplicationUserId { get; set; }

    [ForeignKey("CoveredByApplicationUserId")]
    public virtual ApplicationUser CoveredByApplicationUser { get; set; }

    public virtual bool IsNetworkLoad { get; set; }

    public virtual bool IsExport { get; set; }

    public virtual bool CanTrackLoad { get; set; }

    [Required]
    public virtual DateTime CreatedDateTime { get; set; }

    public virtual DateTime? ModifiedDateTime { get; set; }

    public virtual string BillingReferenceNumber { get; set; }

    [Required]
    public virtual int LoadStatusId { get; set; }

    [ForeignKey("LoadStatusId")]
    public virtual LoadStatus LoadStatus { get; set; }

    public virtual Freight Freight { get; set; }

    public virtual ICollection<LoadOrigin> LoadOrigins { get; set; }

    public virtual ICollection<LoadDestination> LoadDestinations { get; set; }

    public virtual ICollection<LoadNote> LoadNotes { get; set; }

    public virtual ICollection<LoadCarrier> LoadCarriers { get; set; }

}

以我的财产 LoadCarries 为例。 LoadCarries 有一个属性 Carrier,它是从数据库中填充的,没有跟踪。

public partial class LoadCarrier
{
    public virtual int Id {get;set;}

    public virtual bool IsDispatched { get; set; }

    public virtual bool IsPrimary { get; set; }

    [MaxLength(25)]
    public virtual string CarrierProNumber { get; set; }

    [MaxLength(1000)]
    public virtual string RCNotes { get; set; }

    [Required]
    public virtual int CarrierId { get; set; }

    [ForeignKey("CarrierId")]
    public virtual Carrier Carrier { get; set; }

    [MaxLength(50)]
    [Required]
    public virtual string Dispatcher { get; set; }

    public virtual long LoadId { get; set; }

    [ForeignKey("LoadId")]
    public virtual Load Load { get; set; }

    public virtual LoadDriver LoadDriver { get; set; }
}

一旦我正确填充了我的对象,我会尝试保存到数据库中。由于这些对象都已分离,因此保存失败,因为我对 Carriers 对象的成员有唯一约束,因为 EF 错误地尝试插入数据库中已经存在的对象。

    public virtual int Create(T entity, long userId)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }
        dbSet.Add(entity);
        return context.SaveChanges(userId);
    }

我曾多次尝试将 Carriers 对象的状态更改为“未更改”,但我得到了重复的主键异常。我还尝试将 Load 对象添加到上下文中,然后将 Carrier 对象设置为我明确从数据库中提取的对象。有没有办法可以正确附加这个分离的对象?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework-6


    【解决方案1】:

    不要设置 LoadCarrier 的 Carrier 属性,而只设置 CarrierId。 这足以让 EF 知道它必须将外键设置为现有记录。

    还有其他方法可以做到这一点,但由于 Carrier 是分离的,因此最好将其保持连接而不是一开始就将其拉入。我想您正在预装未跟踪的运营商,因为它们是固定的。

    【讨论】:

    • 我也试过这个方法。当我使用 dbSet.Add(entity) EF 从数据库填充 LoadCarrier 但它仍然尝试插入到 Carrier 表中。问题可能是 LoadCarrier 是一个应该插入的新对象,但不应插入其成员 Carrier 并且 LoadCarrier 应该具有 Carrier 的外键。
    • 正如我告诉你的那样,你不设置导航属性,而是设置外键值。因此不会发生任何插入。
    • 这就是我所说的我已经尝试过的。 snag.gy/YO9TE.jpg。如您所见,Carrier 对象为空,但设置了外键 CarrierId。
    • 你确定你得到的异常吗?根据快照,我会说那部分是正确的。 EF 可能与其他一些关系有问题。我认为使用外键是解决问题的关键。
    • 我对 Carrier [Index("IX_MCNumber", IsUnique = true)] 中的属性有限制。这就是抛出的异常。 snag.gy/iM9Ie.jpg
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多