我有一个带有长期运行的EF6 DbContext的winforms应用程序。它是数据库第一个启用了延迟加载的edmx模型。上下文由业务逻辑创建,它是私有的,对项集合的访问是通过业务逻辑。业务逻辑可通过名为DataBridge的单个实例对象获得。
我通过断开托管SQL Server的VM上的网桥,并尝试处理切换到备份来模拟数据库的故障。在我处理完上下文并创建一个新的后,我尝试重新加载数据,当我尝试加载一个特定的列表时,我得到InvalidOperationException ...“无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象。“
以下是BL和来自主要表格的剪切片:
EDIT添加了'上下文'的优势
public class DataBridge
{
private static DataBridge _staticBridge;
private PPIEntitiesCtx _commonContext;
private DataBridge()
{
_commonContext = new PPIEntitiesCtx(ConnectionTools.PrimaryDB);
_commandEx = new CommandExecutor();
}
public static DataBridge Instance
{
get
{
if (_staticBridge == null)
_staticBridge = new DataBridge();
return _staticBridge;
}
}
internal PPIEntitiesCtx Context
{
get
{
return _commonContext;
}
}
public void SelectDB(string connectionStringName)
{
_commonContext.Dispose();
_commonContext = new PPIEntitiesCtx(ConnectionTools.GetConnectionString(connectionStringName));
}
public MemberBL GetMemberBL()
{
try
{
if (_memberBL == null)
_memberBL = new MemberBL(this);
return _memberBL;
}
catch (Exception)
{
throw;
}
}
public WorkLogBL GetWorkLogBL()
{
if (_workLogBL == null)
_workLogBL = new WorkLogBL(this);
return _workLogBL;
}
以下是Form1
的摘录 public Form1()
{
InitializeComponent();
_dataBridge = DataBridge.Instance;
_memberLogic = _dataBridge.GetMemberBL();
_workLogLogic = _dataBridge.GetWorkLogLogic();
}
private void Form1_Load(object sender, EventArgs e)
{
// test connection
// login
LoadData();
}
private void LoadData()
{
try
{
MemberBindingSource.DataSource = _memberLogic.GetBindingList();
// more bindings cut out
// Exception happens in the BL called from here
workLogBindingSource.DataSource = _workLogLogic.GetBindingList();
}
catch (Exception ex)
{
HandleException(ex);
}
}
private void SelectDB()
{
// Show dialog to select new DB
// (selects a connection string name from app.config)
SelectDatabase frm = new SelectDatabase();
frm.ShowDialog();
if (frm != null && frm.selectedItem != null && frm.selectedItem.Length > 0)
{
_dataBridge.SelectDB(frm.selectedItem); // drops and creates a new context
LoadData();
}
}
以下是工作日志BL中引发异常的要点
public class WorkLogBL : BaseBL, IBusinessLogic<WorkLog>
{
public WorkLogBL(DataBridge dataBridge)
{
_dataBridge = dataBridge;
}
public BindingList<WorkLog> GetBindingList()
{
try
{
_dataBridge.Context.WorkLogs
.OrderByDescending(wl => wl.Year)
.ThenByDescending(wl => wl.Month)
.Load();
return _dataBridge.Context.WorkLogs.Local.ToBindingList();
}
catch (Exception)
{
throw;
}
}
}
我不确定堆栈跟踪会有多大帮助,它似乎被截断了......
"The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects."
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.ValidateContextsAreCompatible(RelatedEnd targetRelatedEnd)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges)
at System.Data.Entity.Core.Objects.ObjectStateManager.PerformAdd(IEntityWrapper wrappedOwner, RelatedEnd relatedEnd, IEntityWrapper entityToAdd, Boolean isForeignKeyChange)
at System.Data.Entity.Core.Objects.ObjectStateManager.PerformAdd(IList`1 entries)
at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges()
at System.Data.Entity.Core.Objects.ObjectContext.DetectChanges()
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
at System.Data.Entity.Internal.Linq.InternalSet`1.get_Local()
at System.Data.Entity.DbSet`1.get_Local()
at BusinessLogic.WorkLogBL.GetBindingList() in E:\Reliance\Projects\PCRS\PPI\PPI_DEV\BusinessLogic\WorkLogBL.cs:line 72
第72行是GetBindingList()
的行因此,由于上下文被处理并且正在重新加载新的上下文,因此两个对象如何来自不同的上下文?被绑定到表单上的控件的对象是否会阻止上下文被处理? 我试图在处理上下文之前手动分离所有项目,但这使事情变得更糟。表格试图在删除内容时更新所有内容。
任何帮助将不胜感激。我没有尝试的东西。 TIA, 麦克