这个问题简直要把我逼疯了,特别是因为我怀疑要么有一个简单的解决办法,要么我对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集合中传递的对象,而不是任何在回发后持久化的对象。
这是我自己在类似领域的挣扎中非常悲哀的问题。