【发布时间】:2017-12-01 01:55:01
【问题描述】:
所以,我差不多到此为止了。我是一位经验丰富的程序员和 SQL 用户,但对 Entity Framework 不熟悉。 (使用 VS Pro 2015,EF 6)
这是我在这里的第一篇文章,如果我还没有完成所有协议,请原谅我。
在尝试将实体对象附加到数据库上下文时,我收到错误消息“IEntityChangeTracker 的多个实例无法引用实体对象”。我了解错误的含义:我的对象已附加到上下文。我不明白的是为什么/如何我的对象仍然附加到数据库上下文。
有问题的对象是通过对拥有对象的方法调用获取的:
ActiveWorkSession = tcUser.getActiveWorkSession();
这里是getActiveWorkSession方法:
public EmployeeWorkSession getActiveWorkSession()
{
EmployeeWorkSession activeWS = null;
using (PHSRP_DashboardDataModel _DBC = new PHSRP_DashboardDataModel())
{
var ews = _DBC.EmployeeWorkSessions
.Where(w => (w.EmployeeID == this.EmployeeRecord.EmployeeID) &&
(w.WorkEndDateTime_Actual == null))
.Include(w => w.WorkStartRecords)
.Include(w => w.WorkEndRecords)
.Include(w => w.WorkSessionBreaks);
if (ews.Count() > 0)
{
activeWS = ews.First();
if (ews.Count() > 1)
{
activeWS = ews.Last();
}
}
}
return activeWS;
}
您会看到,除了作为本地范围对象之外,DbContext (_DBC) 在方法返回之前由 using 语句处理。 因此,稍后,我需要再次将此 ActveWorkSession 附加到 DbContext (因为我处理了它的原始上下文!)我首先尝试了这个:
private void btn_UndoButton_Click(object sender, EventArgs e)
{
|
|
// Various condition tests
|
|
tcPunch lPunch = tcLastPunchUndo.LastPunch;
PHSRP_DashboardDataModel _DBC = new PHSRP_DashboardDataModel();
_DBC.EmployeeWorkSessions.Attach(ActiveWorkSession);
// Blows up here ^
switch (lPunch.Type)
{
Cases with try-catch
}
}
这在 Attach 语句中给出了“一个实体对象不能被多个 IEntityChangeTracker 实例引用”。
显然,在某些情况下,我仍然依附于 DbContext,因此我决定使用该上下文:
private void btn_UndoButton_Click(object sender, EventArgs e)
{
|
|
// Various condition tests
|
|
tcPunch lPunch = tcLastPunchUndo.LastPunch;
PHSRP_DashboardDataModel _DBC;
if (GetDbContextFromEntity(ActiveWorkSession)!=null) // is ActiveWorkSession still attached to a Dbcontext ?
{
_DBC = (PHSRP_DashboardDataModel) GetDbContextFromEntity(ActiveWorkSession); // Get that Context
// Blows up here ^
}
else
{
_DBC = new PHSRP_DashboardDataModel(); // Open new context and attach
_DBC.EmployeeWorkSessions.Attach(ActiveWorkSession);
}
switch (lPunch.Type)
{
// Cases with try-catch
}
}
GetDbContextFromEntity 代码来自 StackOverflow 的答案
这当然给了我一个 InvaildCastException:“无法将 'System.Data.Entity.DbContext' 类型的对象转换为 'PHSRP_Dashboard.PHSRP_DashboardDataModel'。”当我尝试将 DbContext 的基本类型转换为我的 PHSRP_DashboardDataModel 派生类型时。我知道那是我的一厢情愿。
所以我正在寻找解决方案。我很灵活。一种将 ActiveWorkSession 与其现有 dbcontext 断开连接的方法,或者一种正确处理该现有上下文的方法,或者我还没有看到的其他一些选项。
谢谢。
将我的查询(按照 Frank 的建议)修改为:
var ews = _DBC.EmployeeWorkSessions
.Where(w => (w.EmployeeID == this.EmployeeRecord.EmployeeID) &&
(w.WorkEndDateTime_Actual == null))
.Include(w => w.WorkStartRecords)
.Include(w => w.WorkEndRecords)
.Include(w => w.WorkSessionBreaks)
.AsNoTracking();
没有解决问题-同样的错误
【问题讨论】:
标签: c# .net entity-framework entity-framework-6