我收到的错误-
“ System.ArgumentException”类型的未处理异常发生在 mscorlib.dll
其他信息:值“ PHSRP_Dashboard.WorkSessionBreak” 不是类型 “ System.Data.Entity.DynamicProxies.WorkSessionBreak_06908 <.. many 个字符。> 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);
}
我们从中返回的对话框表单正常工作。更改/添加已正确放置在数据库中,但是与此父窗体关联的BindingSources不会自动重新排序。
对调试器中变量内容的检查表明,LINQ返回的Enumerable中的New记录是WorkSessionBreak,而其他先前存在的项目是WorkSessionBreak 代理
排序有效,但也返回类型和代理的混合:
下一条指令崩溃是因为一项与另一项的类型不同(即代理)。
我不知道该怎么办或为什么会发生。该算法可用于相同形式的其他部分,而不会发生此错误。
答案 0 :(得分:1)
您面临的是deferred execution。基本上,代码试图将项目添加到数据库查询中。
这里:
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()
调用是执行查询的对象,因此结果得以实现。