c# - 我的一个实体不是代理
问题描述
我收到的错误-
mscorlib.dll 中出现“System.ArgumentException”类型的未处理异常
附加信息:值“PHSRP_Dashboard.WorkSessionBreak”不是“System.Data.Entity.DynamicProxies.WorkSessionBreak_06908<..many characters..>6E3E”类型,不能在此通用集合中使用。
仅在将新的 WorkSessionBreak 记录添加到数据库时发生。它不会发生在仅被修改的记录中,也不会在重新启动程序并且重新访问(不是这样)新记录时再次发生。
private void Edit_WorkSessionBreak_FormClosed(object sender, FormClosedEventArgs e)
{
if (SelectedWorkSessionID >= 0)
{
var BreakSet = editEmployee.EmployeeWorkSessions
.SelectMany(ws => ws.WorkSessionBreaks)
.Where(b => b.DELETED != true && b.EmployeeWorkSessionID == SelectedWorkSessionID);
if (BreakSet.Any())
{
var BreakSetSorted = BreakSet.OrderBy(b => b.OutTime);
this.bs_WorkSessionBreaks_Display.DataSource = BreakSetSorted; // Blows-up on New record added.
}
else
{
this.bs_WorkSessionBreaks_Display.DataSource = new BindingList<WorkSessionBreak>();
}
}
else
{
this.bs_WorkSessionBreaks_Display.DataSource = new BindingList<WorkSessionBreak>();
}
if (bs_WorkSessionBreaks_Display.Count > 0)
{
if (syncToViewBreak(((WorkSessionBreak)bs_WorkSessionBreaks_Display.Current).WorkSessionBreakID))
{
SelectedWorkSessionBreakID = ((WorkSessionBreak)bs_WorkSessionBreaks_Display.Current).WorkSessionBreakID;
}
}
bs_WorkSessionBreaks_Display.ResetBindings(false);
}
我们返回的 Dialog 表单工作正常。更改/添加已正确放置在数据库中,但与此 Parent 表单关联的 BindingSources 不会自动重新排序。
检查调试器中的变量内容表明 LINQ 返回的 Enumerable 中的新记录是 WorkSessionBreak 而其他预先存在的项目是 WorkSessionBreak Proxies。
排序工作但也返回类型和代理的混合:
下一条指令崩溃,因为一个项目与其他项目的类型不同(即代理)。
我不知道该怎么办或为什么会发生。此算法用于相同形式的其他部分,不会发生此错误。
解决方案
您面临的是所谓的延迟执行。基本上,代码试图将项目添加到数据库查询中。
这里:
var BreakSet = editEmployee.EmployeeWorkSessions
.SelectMany(ws => ws.WorkSessionBreaks)
.Where(b => b.DELETED != true
&& b.EmployeeWorkSessionID == SelectedWorkSessionID);
BreakSet
是一个IQueryable<WorkSessionBreak>
。每当您看到IQueryable<SomeClass>
时,请记住它代表一个查询,并且(通常)不是您在内存中的数据。
var BreakSet = editEmployee.EmployeeWorkSessions
.SelectMany(ws => ws.WorkSessionBreaks)
.Where(b => b.DELETED != true
&& b.EmployeeWorkSessionID == SelectedWorkSessionID)
.OrderBy(b => b.OutTime)
.ToList();
if (BreakSet.Any())
{
this.bs_WorkSessionBreaks_Display.DataSource = BreakSet;
}
有了这个,你现在有一个单一的数据库调用。该OrderBy
子句不会影响COUNT
查询的结果,因此您可以将其作为初始查询的一部分。请注意,最后的ToList()
调用是执行查询的原因,因此结果被具体化。
推荐阅读
- c++ - C++ 中的 3D 运动场
- reactjs - 与 React-Native 和 React 导航一起使用时,上下文 API 返回 undefined 不是对象
- javascript - 是否可以对同一元素使用 2 种不同的字体,一种用于英语,另一种用于泰米尔语(unicode)
- python - Python中的乐透抽奖模拟
- html - 如何使图像渲染 Elm?
- python - 写入 CSV 文件时,Pandas 数据框的大小会爆炸
- python - DRF 反向找不到视图名称
- ruby-on-rails - 查看在 ruby on rails 中调用类方法?
- css - 主菜单在我的笔记本电脑上运行良好,但在手机上却不行
- java - 如何在抽屉菜单中获取登录用户的信息?