Обновление сложного объекта с помощью linq и Entity Framework - PullRequest
0 голосов
/ 22 июня 2011

У меня есть объект, который называется Order, который имеет несколько свойств, которые также являются объектами.когда я обновляю объект Order, простые свойства обновляются правильно, но сложные (которые находятся в разных таблицах) не обновляются, а вместо этого создаются новые.Что я делаю неправильно.Кроме того, когда я пытаюсь получить свойство нескольких элементов (элементы в этом примере), он возвращает ноль, а не сохраненные элементы.

Пример кода:

[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 Ответ

1 голос
/ 22 июня 2011

Если вы не хотите вставлять новые объекты для своих свойств навигации, вы должны прикрепить их к контексту, прежде чем присваивать значения. Для вашей проблемы с коллекцией предметов вы должны включить коллекцию при запросе. Включение двух других навигационных свойств не является обязательным, и установка состояния Modified вручную также в вашем примере. Для Include вы можете использовать строго типизированную версию в EF 4.1 с лямбда-выражением:

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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...