试图保存已存储在ASP中的实体.. NET控件状态使用EntityFramework



这个问题简直要把我逼疯了,特别是因为我怀疑要么有一个简单的解决办法,要么我对EF要求太高了……

情况是这样的:

我有一个用户控件(ASCX),它基本上是作为EF实体的编辑表单。当控件databinds时,我按ID从数据库中取出对象并将其置于控件状态(通过覆盖SaveControlState()LoadControlState())。

用户然后继续他们的快乐的方式做任何改变或什么不。这个对象上有导航属性,所以当他们对导航属性进行更改时,比如通过向对象上的位置集合添加位置,我正在更新控制状态的dataItem

最后,在用户完成所有操作并单击保存按钮之后,我尝试使用以下代码保存或创建记录:

protected void SaveButton_Click(object sender, EventArgs e)
{
    DepartmentLookup dept = Master.DataContext
        .Departments.Find(ResourceDepartment.SelectedValue.ToInt());
    LocationLookup location = dataItem.Locations[ResourceLocation.SelectedIndex];
    if (dataItem.OfficeLocation == null)
    {
        dataItem.OfficeLocation = new OfficeLocationLookup()
        {
            Location = location,
            OfficeLocationName = location.LocationName
        };
    }
    else if (!dataItem.OfficeLocation.Location.Equals(location))
    {
        dataItem.OfficeLocation.Location = location;
        dataItem.OfficeLocation.OfficeLocationName = location.LocationName;
    }
    foreach (LocationLookup loc in dataItem.Locations)
    {
        if (loc.LocationTypeID == default(int))
        {
            LocationTypeLookup locType = Master.DataContext
                .LocationTypes.SingleOrDefault(lt =>
                    lt.LocationType == loc.LocationType.LocationType);
            if (locType != null)
                loc.LocationType = locType;
        }
        else
        {
            LocationTypeLookup locType = Master.DataContext
                .LocationTypes.Find(loc.LocationTypeID);
            if (locType.LocationType != loc.LocationType.LocationType)
            {
                LocationTypeLookup newType = new LocationTypeLookup()
                {
                    LocationType = loc.LocationType.LocationType
                };
                loc.LocationType = newType;
            }
        }
    }
    dataItem.PrimaryPhone = PrimaryPhone.Text;
    dataItem.CellPhone = CellPhone.Text;
    dataItem.Department = dept;
    dataItem.EmailAddress = EmailAddress.Text;
    dataItem.LastModifiedBy = HttpContext.Current.User.Identity.Name;
    dataItem.LastModifiedDtm = DateTime.UtcNow;
    if (dataItem.ResourceID == default(int))
        Master.DataContext.Resources.Add(dataItem);
    else
    {
        DbEntityEntry<Resource> entry = Master.DataContext.Entry<Resource>(dataItem);
        if (entry != null && entry.State == EntityState.Detached)
        {
            Master.DataContext.Resources.Attach(dataItem);
            // entry.State = EntityState.Modified;
        }
    }
    Master.DataContext.SaveChanges();
}

我尝试了许多不同的方法来尝试将对象保存到数据库,所有这些都导致了各种错误。唯一没有抛出异常的方法是SetValues方法,它也没有保存任何导航属性,因此被证明是没有价值的。

任何帮助或建议都将不胜感激,因为我已经为这个问题绞尽脑汁了几天了。

提前感谢!J

在会话中保存实体对象(而不是控件状态)时,我遇到了类似的问题。问题是,检索到的对象有各种不同的objectcontext,这导致保存失败。

这取决于你如何管理上下文,但最好的想法是将上下文与Request对象关联起来,并使用工厂类来检索它,因此你每个请求使用一个上下文。

HttpContext.Current.Items["Context"] = context

任何其他模式都给我带来了大麻烦。

根据我的经验,由于管理上下文的困难,将整个实体保存在会话(或ControlState)中并不是一个好主意。即使使用了上述(非常安全的)模式,上下文也会来自不同的请求。我最终只是将对象id保存到会话(ControlState)中,并使用包装器类来检索它们。我持久化了我想在Request集合中传递的对象,而不是任何在回发后持久化的对象。

这是我自己在类似领域的挣扎中非常悲哀的问题。

最新更新