使用linq和实体框架更新复杂对象

使用linq和实体框架更新复杂对象,linq,entity-framework-4.1,Linq,Entity Framework 4.1,我有一个对象,叫做Order,它有几个属性,这些属性也是对象。当我更新Order对象时,简单的属性被正确地更新,但是复杂的属性(位于不同的表中)没有被更新,而是创建了新的属性。我做错了什么。此外,当我尝试获取多个项目属性(本例中为项目)时,它返回null,而不是保存的项目 代码示例: [DataContract] public class Order { [Key] [DataMember] public int Id { get; set; } #region

我有一个对象,叫做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();
[DataContract]
公共阶级秩序
{
[关键]
[数据成员]
公共int Id{get;set;}
#地区订单详情
[数据成员]
公共int?引用编号{get;set;}
[数据成员]
公共虚拟状态CurrentStatus{get;set;}
[数据成员]
公共日期时间?CurrentStatusUpdateOn{get;set;}
[数据成员]
[MaxLength(1024)]公共字符串ArchiveFileName{get;set;}
[数据成员]
公共双总价{get;set;}
[数据成员]
公共布尔数字签名{get;set;}
[数据成员]
public int DigitalSigningReferenceId{get;set;}
[数据成员]
公共虚拟优先级{get;set;}
[数据成员]
公共虚拟ICollection项{get;set;}
.....
}
[数据合同]
公共类项目:IItem
{
[数据成员]
[关键]
公共int Id{get;set;}
[数据成员]
公共虚拟顺序ParentOrder{get;set;}
[数据成员]
公共虚拟ItemType类型{get;set;}
[数据成员]
公共字符串ItemReference{get;set;}
[数据成员]
公共int引用{get;set;}
[数据成员]
公共整数数量{get;set;}
[数据成员]
公共十进制价格{get;set;}
[数据成员]
公共字符串名称{get;set;}
....
}
私有静态bool UpdateOrderDetails(订单、数据库上下文)
{
var savedOrder=
context.Orders.Include(“优先级”).Include(“当前状态”).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(order.Items中的变量项)
{
var savedItem=savedOrder.Items.Single(x=>x.ItemReference==item.ItemReference);
if(savedItem!=null)
{
savedItem.Price=项目价格;
savedItem.Quantity=物料.Quantity;
}
}
}
context.Entry(savedOrder).State=EntityState.Modified;
var i=context.SaveChanges();

如果您不想为导航属性插入新对象,则必须在分配值之前将其附加到上下文中。对于项目集合问题,您需要在查询时包含集合。不需要包含其他两个导航属性,并将状态设置为
已修改在您的示例中都不是。对于
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();
    }
}

order
savedOrder
是否从同一上下文中创建?是否将
order
对象从上下文中分离?谢谢@Slauma,我正在尝试您的方法,我收到以下错误:指定的包含路径无效。EntityType“Moj.FE.Data.order”未声明名为“Items”的导航属性。@Etchin:Strange.
Items
是什么?您在代码中使用的是
order.Items
。您能否显示
order
类在您的模型中是如何定义的?(您可以编辑问题以显示该类。)@艾金:非常奇怪。这应该真的能用。你有流畅的API代码吗?你的上下文类是什么样子的?什么是
IItem
?你的数据库中的Items表是否有顺序的外键,比如
ParentOrder\u Id
order\u Id
?@Slauma:你尝试过使用System.Data.Entity;t添加吗o包含UpdateOrderDetails()方法的类?这修复了我遇到的一个类似问题,其中Include()方法不会采用lambda表达式(ie仅适用于包含导航属性名称的字符串。@HOCA:我想,这不是原因。这是一个运行时错误。如果
使用System.Data.Entity
将丢失,我们将在编译时出错。