我的查询是:
var ReadAndUnreadMessages =
(from m in MDB.Messages
orderby m.Date descending
where m.ID_Receive == (Guid)USER.ProviderUserKey && m.Delete_Admin == false
select new AllMessages()
{
id = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).ID_Message,
parent = (Guid)(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).ID_Message_Parent,
sender = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).ID_Sender,
receiver = (Guid)USER.ProviderUserKey,
subject = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Subject.Subject1.ToString() == "Other" ?
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Other_Subject
:
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Subject.Subject1.ToString(),
body = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Body.Length > 26 ?
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Body.Substring(0, 25) + "..."
:
(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Body,
date = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).Date.ToShortDateString(),
read =(LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).IsRead,
finished = (LoadMessageChildren(m.ID_Message)[LoadMessageChildren(m.ID_Message).Count - 1] as Message).IsFinished,
count = MessageClass.LoadAll(m.ID_Message).Count
}).ToList();
,例外是:
参数'value'是错误的类型。预期的'消息'。实际的'System.Object'。
这意味着什么?
LoadMessageChildren:
public static ArrayList LoadMessageChildren(Guid Parent)
{
ArrayList arr = new ArrayList();
Guid id = Parent;
while (id != Guid.Empty)
{
arr.Add(LoadMessage(id));
try
{
id = (Guid)MDB.Messages.Single(a => a.ID_Message_Parent == id).ID_Message;
}
catch
{
id = Guid.Empty;
}
}
return arr;
}
LoadMessage:
public static Message LoadMessage(Guid id)
{
var mess = from m in MDB.Messages
where m.ID_Message == id
select m;
return mess.Single();
}
答案 0 :(得分:5)
代码不可读,并且是代码重复的错误情况(以及LoadMessageChildren
的多次执行)。
首先,请考虑以下事项:
from m in MDB.Messages
orderby m.Date descending
where m.ID_Receive == (Guid)USER.ProviderUserKey && m.Delete_Admin == false
let children = LoadMessageChildren(m.ID_Message)
let lastChildMessage = children.Last()
select new AllMessages()
{
id = lastChildMessage.ID_Message,
...
}
这可以解决您的问题,因为它是might be caused by using the []
indexer
除此之外,尚不清楚发布的代码是否导致异常。
答案 1 :(得分:0)
错误很可能是由ArrayList
。
问题是LINQ旨在与实现System.Collections.Generic.IEnumerable<T>
接口的泛型集合一起使用。 ArrayList
是一个非泛型集合,在内部将所有内容存储为Object。因此,当您从ArrayList中检索某些内容时,需要将其强制转换为Message
。
查看您的错误消息,它看起来像某个Message
对象,但是当发生该引用时,您的ArrayList中的实例(Object
)不会被转换为Message
对象。此外,ArrayList
未实现IEnumerable<T>
接口,这可能会在某些情况下让您陷入麻烦。
如何解决?
我建议您更改LoadMessageChildren
的实施,以使用generic list(List<Message>
):
public static List<Message> LoadMessageChildren(Guid Parent)
{
List<Message> arr = new List<Message>();
Guid id = Parent;
while (id != Guid.Empty)
{
arr.Add(LoadMessage(id));
try
{
id = (Guid)MDB.Messages.Single(a => a.ID_Message_Parent == id).ID_Message;
}
catch
{
id = Guid.Empty;
}
}
return arr;
}
在检索/引用项目方面,您还必须更改与通用列表交互的代码。但那只是语法。由于存在与列表和项目交易的等效方法。
从ArrayList
切换到List<T>
,在性能和编译时验证方面也有优势。 ArrayList
基本上是.Net Framework 1.0版本的继承,当时没有对泛型的支持,它只是出于兼容性原因而被保留在框架中。
有更大的benefits for using generics。
更新的答案:
“方法”System.Collections.Generic.List'1 [Message] LoadMessageChildren(System.Guid)'没有支持的SQL转换“您获得的异常是由事实引起的您的LoadMessageChildren
方法未映射到数据库中的存储过程或用户定义的函数。
您不能在LINQ to SQL查询中调用任何常规C#方法。 LINQ to SQL object model将查询中的方法解释为存储过程或用户定义的函数。因此,引擎基本上寻找一种名为LoadMessageChildren
的方法,该方法映射到数据库中的存储过程或用户定义的函数。因为没有映射,它会告诉您no supported translation to SQL
已找到。 LINQ to SQL object model链接向您展示了如何使用方法属性来映射执行存储过程的方法。
您现在有几个选择:
joins
选择子消息答案 2 :(得分:0)
我唯一看到你使用LoadChildMessages()的方法是让孩子的消息计数......除非我错了,我认为你可以把它写成一个连接。您在查询中执行了大量查询,这些查询似乎不是必需的,并且可能导致对数据库的多次命中。我的问题是,为什么你的dmbl / sql数据库中没有关系,以便LinqToSql知道创建一个属性为List<Message> ChildMessages
但这是我的看法:
var query = from message in MDB.Messges
join childmessage in MDB.Messages.Where(child => child.ID_Message_Parent == message.ID_Message) into childMessages
from childMessage in childMessages.DefaultIfEmpty() // This creates a
// left outer join so you get parent messages that don't have any children
where message.ID_Receive == (Guid)USER.ProviderUserKey && message.Delete_Admin == false
select new AllMessages()
{
id = message.ID_Message,
parent = message.ID_Message_Parent,
sender = message.ID_Sender,
receiver = (Guid)USER.ProviderUserKey,
subject = message.Subject.Subject1.ToString() == "Other" ?
message.Other_Subject
:
message.Subject.Subject1.ToString(),
body = message.Body.Length > 26 ?
message.Body.Substring(0, 25) + "..."
:
message.Body,
date = message.Date.ToShortDateString(),
read =message.IsRead,
finished = message.IsFinished,
count = childMessage.Count() // This might have to be this
//count = childMessage == null ? 0 : childMessage.Count()
};
var ReadAndUnreadMessages = query.ToList();
但很难说,因为我无法运行代码......如果有效,请回复并告诉我。
注意:我建议使用一个链接到DataContext.Log属性的类,该类将生成的TSQL代码写入调试器窗口。这是关于writing your own的文章。当我对数据库进行不必要的调用时,它确实帮助我。