在Win7应用程序中,我尝试更新名为“Channel”的ADO.NET数据库表中的几个字段,其EntitySetMapping名称为“Channels”,使用EF中的EntityClient访问SqlServerCe 3.5(IPManager_DBEntities)。 / p>
使用VS 2010 IDE,代码编译良好,Intellisense没有抱怨。 Channel数据表的格式在底部引用,因为一行中的各个字段(由Channel“Number”选择)需要用从代码传递给它的信息更新,为了简单起见未示出。在过去的几天里,我没有用谷歌搜索解决了我的类型铸造困境。使用LINQ,我得到了这个RunTime异常:
“无法将类型为'System.Data.Objects.ObjectQuery`1 [Manager.Data.Channel]'的对象强制转换为'Manager.Data.Channel'”。
// Update channel status with information parsed from the data packet.
using (IPManager_DBEntities context = new IPManager_DBEntities())
{
Channel thisChannelRow = (Channel)(from CE
in context.Channels
where CE. Number == int.Parse(IDLine[2])
select CE);
// Throwing exception after setting up this query:
// "Unable to cast object of type 'System.Data.Objects.ObjectQuery`1
// [Manager.Data.Channel]' to type 'Manager.Data.Channel'"
// During debug sessions, "thisChannelRow" is null as a result.
MessageBox.Show("thisChannelRow. Channel = " + thisChannelRow.Number );
ThisChannel.StatusID = int.Parse(IDLine[5]);
ThisChannel.Cycle = int.Parse(IDLine[4]);
ThisChannel.Modified = DateTime.Now;
context.SaveChanges();
}
我希望有人有解决方案来帮助我渡过难关。
答案 0 :(得分:4)
LINQ查询返回IEnumerable<T>
的类型后代的对象,而不是Channel
,即使序列中只有一个项目。要获取实际项目,请使用FirstOrDefault
:
Channel thisChannelRow = (Channel)(from CE
in context.Channels
where CE. Number == int.Parse(IDLine[2])
select CE).FirstOrDefault();
或First
,Single
或SingleOrDefault
,如果其中任何一种更适合。
答案 1 :(得分:0)
我很确定你的第一个命令是返回IEnumerable
,它与它枚举的对象的类型不同。
尝试将.First()
添加到LINQ ala LINQ Select First
这是必需的,因为您的原始LINQ语句返回的类型IEnumerable<Channel>
与Channel
不同,因此您的类型不匹配。您可以将初始LINQ语句视为返回事物列表,但是您尝试将该列表放入单个项目中。最后的.First()
告诉计算机只从该列表中获取第一个元素并仅返回该元素。因此,使用更新的LINQ语句,您现在将Channel
存储在Channel
中,因此不再存在类型不匹配。
答案 2 :(得分:0)
在我的情况下,我可以使用AddRange方法修复它。
Public Function GetMessages(ByVal Issue As Issue) As List(Of Message)
Dim Res As New List(Of Message)
If Issue IsNot Nothing Then
Dim db As New ProjectManagerEntities
Res.AddRange(From item As Message In db.Messages
Where item.IssueSet_Id = Issue.Id _
Select item)
End If
Return Res
End Function