【发布时间】:2011-03-15 09:28:41
【问题描述】:
我正在使用 linq-to-sql Concat() 处理异常
我有 2 张桌子。 第一个表 ParsedMessages 具有以下字段
* ParsedMessageID (int)
* MessageTypeID (int)
* TextMessage (varchar(max))
第二个表 ParsedMessageLinks 有以下字段
* ParsedMessageID (int)
* AnotherID (int)
* NumberOfOccurences (int)
这是我需要使用单个 linq 查询来实现的,但我不确定它是否可能。
通过连接,检索链接到某个 AnotherID 的 ParsedMessage 记录。在示例 SQL 和 linq 代码中,AnotherID 的值为 0 只是为了提供示例。
对于每个 ParsedMessage 记录,我还需要 NumberOfOccurences(表 #2 的字段)
仅检索每个 MessageTypeID 的前 (100) 个 ParsedMessage 记录。例如,如果 ParsedMessages 中有 275 条记录链接到 AnotherID==0,其中前 150 条记录的 MessageTypeID == 0,其余 125 条记录的 MessageTypeID == 1,我希望我的查询最终返回 200 条记录, MessageTypeID == 0 的 top(100) 和 MessageTypeID == 1 的 top(100)
经过大量搜索,我发现我想要做的纯 SQL 等价物就是这样。我知道这首先存在,但我一开始试图在没有 Union 的情况下找到其他东西但没有这样做(我的 SQL 知识不是很好):
选择 TOP(100) PM.*, PML.NumberOfOccurences 来自 ParsedMessages PM INNER JOIN ParsedMessageLinks PML ON PM.ParsedMessageID = PML.ParsedMessageID WHERE PML.AnotherID = 0 和 PM.MessageTypeID = 0 ORDER BY PM.ParsedMessageID DESC UNION ALL
选择 TOP(100) PM.*, PML.NumberOfOccurences 来自 ParsedMessages PM INNER JOIN ParsedMessageLinks PML ON PM.ParsedMessageID = PML.ParsedMessageID WHERE PML.AnotherID = 0 和 PM.MessageTypeID = 1 ORDER BY PM.ParsedMessageID DESC UNION ALL
选择 TOP(100) PM.*, PML.NumberOfOccurences 来自 ParsedMessages PM INNER JOIN ParsedMessageLinks PML ON PM.ParsedMessageID = PML.ParsedMessageID WHERE PML.AnotherID = 0 和 PM.MessageTypeID = 2 按 PM.ParsedMessageID DESC 排序
所以基本上,检索我需要的数据的唯一方法是一次执行 3 个 sql 查询,其中每个查询只有 PM.MessageTypeID 不同。
现在我想使用 linq-to-sql 来实现这一点。谷歌搜索后,我发现我可以使用 Linq Concat() 方法来重现 SQL Union All。 以下是一些指向我认为可行的链接: http://blog.benhall.me.uk/2007/08/linq-to-sql-difference-between-concat.html
EF. How to union tables, sort rows, and get top entities?
我最终遇到了这个异常: System.IndexOutOfRangeException : "索引超出了数组的范围。"
这是错误代码:
IQueryable<MyObject> concatquery;
int[] allMessageTypeIDs = new int[] { 0, 1, 2 };
for (int mt = 0; mt < allMessageTypeIDs.Length; mt++)
{
if (mt == 0)
{
concatquery = (from pm in db.ParsedMessages
join pml in db.ParsedMessageLinks on pm.ParsedMessageID equals pml.ParsedMessageID
where pml.AnotherID == 0 && pm.MessageTypeID == allMessageTypeIDs[mt]
orderby pm.ParsedMessageID descending
select new MyObject
{
NumberOfOccurences = pml.Occurrences,
ParsedMessage = pm
}).Take(100);
}
else
{
concatquery = concatquery.Concat(from pm in db.ParsedMessages
join pml in db.ParsedMessageLinks on pm.ParsedMessageID equals pml.ParsedMessageID
where pml.AnotherID == 0 && pm.MessageTypeID == allMessageTypeIDs[mt]
orderby pm.ParsedMessageID descending
select new MyObject
{
NumberOfOccurences = pml.Occurrences,
ParsedMessage = pm
}).Take(100);
}
}
var results = concatquery.ToArray();
为了简单起见,我已经声明了 int 数组 allMessageTypeIDs。但请记住,它持有的值可能会有所不同,这就是我添加 for 循环的原因。以这种方式在循环中使用 Concat() 可能是“非法的”,但我找不到有关此异常的任何相关信息。
MyObject 类基本上包含一个 int (NumberOfOccurences) 和一个 ParsedMessage 数据库对象,仅此而已。
关于我的代码可能有什么问题导致异常的任何建议?
谢谢 弗朗西斯
【问题讨论】:
标签: c# linq-to-sql