加载新的DbContext时,InvalidOperationException“不同的ObjectContext对象”

时间:2016-05-01 02:27:17

标签: c# winforms entity-framework dbcontext

我有一个带有长期运行的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, 麦克

0 个答案:

没有答案