我遇到了ObjectContext.SaveChanges方法的问题:
public void Save(Action<object, object> action)
{
EventAggregator.GetEvent<EntityServiceRequestingEvent>().Publish(true);
var bw = new BackgroundWorker();
var saved = false;
bw.DoWork += (o, ee) =>
{
ProgramStatusService.Status = Resources.DatabaseSavingMessage;
if (!CanSave())
{
throw new InvalidOperationException(
"You must not call Save when CanSave returns false.");
}
try
{
lock (Context)
{
Context.SaveChanges();
saved = true;
}
}
catch (ValidationException e)
{
MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
Resources.SaveErrorInvalidEntities,
e.Message));
}
catch (UpdateException e)
{
var innerException = e.InnerException as SqlException;
if (innerException != null && innerException.Number == 2601)
{
MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
Resources.DublicateKeyUpdateError,
e.InnerException.Message));
}
else
{
MessageService.ShowError(null, string.Format(CultureInfo.CurrentCulture,
Resources.SaveErrorInvalidFields,
e.InnerException.Message));
}
}
ee.Result = saved;
};
bw.RunWorkerCompleted += (o, e) =>
{
EventAggregator.GetEvent<EntityServiceRequestingEvent>().Publish(false);
ProgramStatusService.Status = Resources.ProgramReadyMessage;
if (e.Result != null) action.Invoke(this, e.Result);
};
bw.RunWorkerAsync();
}
保存时我收到错误:调用线程无法访问此对象,因为另一个线程拥有它。在Designer.cs中:
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=true)]
[DataMemberAttribute()]
public Nullable<global::System.DateTime> MDate
{
get
{
return _MDate;
}
set
{
OnMDateChanging(value);
ReportPropertyChanging("MDate");
_MDate = StructuralObject.SetValidValue(value);
ReportPropertyChanged("MDate");// **ERROR HERE**
OnMDateChanged();
}
}
如何在BackgroundWorker中正确使用ObjectContext?
答案 0 :(得分:5)
在后台工作程序中使用上下文的唯一正确方法是在DoWork
处理程序中创建它,使用它并在DoWork
处理程序结束之前处置它。 ObjectContext
不是线程安全的,为SaveChanges
锁定它不会改变它。
您收到的异常不是由EF引起的,而是由WPF和UI控件引起的。您无法从非UI线程修改控件。您必须使用Dispatcher来处理控件。