使用linq和Entity Framework更新复杂对象

时间:2011-06-22 14:09:09

标签: linq entity-framework-4.1

我有一个名为Order的对象,它有几个属性也是对象。当我更新Order对象时,简单的属性会正确更新,但复杂的属性(驻留在不同的表中)不会被更新,而是创建新的属性。我究竟做错了什么。此外,当我尝试获取多项属性(此示例中的项目)时,它返回null而不是保存的项目。

代码示例:

[DataContract]
public class Order
{
    [Key]
    [DataMember]
    public int Id { get; set; }

    #region Order Details

    [DataMember]
    public int? ReferenceNumber { get; set; }

    [DataMember]
    public virtual Status CurrentStatus { get; set; }
    [DataMember]
    public DateTime? CurrentStatusUpdatedOn { get; set; }

    [DataMember]
    [MaxLength(1024)] public string ArchiveFileName { get; set; }

    [DataMember]
    public double TotalPrice { get; set; }

    [DataMember]
    public bool DigitallySigned { get; set; }
    [DataMember]
    public int DigitalSigningReferenceId { get; set; }

    [DataMember]
    public virtual Priority Priority { get; set; }

    [DataMember]
    public virtual ICollection<Item> Items { get; set; }
            .....
            }

[DataContract]
public class Item : IItem
{
    [DataMember]
    [Key]
    public int Id { get; set; }

    [DataMember]
    public virtual Order ParentOrder { get; set; }

    [DataMember]
    public virtual ItemType Type { get; set; }

    [DataMember]
    public string ItemReference { get; set; }

    [DataMember]
    public int FeeReference { get; set; }

    [DataMember]
    public int Quantity { get; set; }

    [DataMember]
    public decimal Price { get; set; }

    [DataMember]
    public string Name { get; set; }
            ....
           }

private static bool UpdateOrderDetails(Order order, DatabaseContext context)
    {
        var savedOrder =
            context.Orders.Include("Priority").Include("CurrentStatus").Where(o => o.Id == order.Id).FirstOrDefault();

            //context.Orders.SingleOrDefault(o => o.Id == order.Id);
        if (savedOrder != null)
        {
            savedOrder.Priority = order.Priority;
            savedOrder.ReferenceNumber = order.ReferenceNumber;
            savedOrder.ShohamId = order.ShohamId;
            savedOrder.TotalPrice = order.TotalPrice;
            savedOrder.UpdatedOn = DateTime.Now;
            savedOrder.CreatedOn = order.CreatedOn;
            savedOrder.ArchiveFileName = order.ArchiveFileName;
            savedOrder.ClientEmail = order.ClientEmail;
            savedOrder.ClientFirstName = order.ClientFirstName;
            savedOrder.ClientIdentificationNumber = order.ClientIdentificationNumber;
            savedOrder.ClientIdentificationType = order.ClientIdentificationType;
            savedOrder.ClientLastName = order.ClientLastName;
            savedOrder.ClientPrimaryPhone = order.ClientPrimaryPhone;
            savedOrder.ClientSecondaryPhone = order.ClientSecondaryPhone;
            savedOrder.CurrentStatus = order.CurrentStatus;
            savedOrder.CurrentStatusUpdatedOn = order.CurrentStatusUpdatedOn;
            savedOrder.DigitallySigned = order.DigitallySigned;
            savedOrder.DigitalSigningReferenceId = order.DigitalSigningReferenceId;

            if (order.Items != null)
            {
                foreach (var item in order.Items)
                {
                    var savedItem = savedOrder.Items.Single(x => x.ItemReference == item.ItemReference);
                    if (savedItem != null)
                    {
                        savedItem.Price = item.Price;
                        savedItem.Quantity = item.Quantity;
                    }
                }
            }

            context.Entry(savedOrder).State = EntityState.Modified;
            var i = context.SaveChanges();

1 个答案:

答案 0 :(得分:1)

如果您不想为导航属性插入新对象,则必须在分配值之前将它们附加到上下文。对于您的项目收集问题,您需要在查询时包含该集合。不必包括其他两个导航属性,并且在您的示例中也不会手动将状态设置为Modified。对于Include,您可以在EF 4.1中使用带有lambda表达式的强类型版本:

private static bool UpdateOrderDetails(Order order, DatabaseContext context)
{
    var savedOrder = context.Orders.Include(o => o.Items)
                         .Where(o => o.Id == order.Id)
                         .FirstOrDefault();

    if (savedOrder != null)
    {
        context.Priorities.Attach(order.Priority);
        context.CurrentStati.Attach(order.CurrentStatus);

        savedOrder.Priority = order.Priority;

        // etc.

        var i = context.SaveChanges();
    }
}