【发布时间】:2009-08-27 21:31:06
【问题描述】:
好的,
我上次发布这个(上周)时,我没有正确描述问题。我已经创建了这个问题的快速示例。查询本地集合可以很好地使用它作为基本查询的一部分。我发现的问题是将它与子查询的一部分一起使用。例如。
如果不给你们一个数据库图或代码图,这很难描述,但我会尽力而为。我正在尝试通过对数据库的一个查询来执行我的代码。我不想分解它并发送多个命令。这样做有一些好处,包括避免可能出现的问题,我将在最后解释。
我正在加入一些有关系的表。属性 (DataEventAttributes) 表当然描述了主表 (DataEvents) 中特定行所特有的属性。
当我在没有任何本地集合的情况下查询它时,对我的 20 gig 数据库来说,事情工作得很好并且非常快。但是,如果我将本地值集合扔到获取结果的子查询的一部分中,我将得到“不支持具有本地集合的查询”
这对我来说很难在我的代码中重现,所以我会尽我所能评论它,你可以按照我在做什么。
// gets the initial query and join. We actually only care about the ID in the end, but we use the joined data
// to determine if a row needs to be pulled.
var initialQuery = from dataEvent in DataEvent.GetByQueryExpression(context)
join attribute in DataEventAttribute.GetByQueryExpression(context) on dataEvent.DataEventID
equals attribute.DataEventID
select new
{
ID = dataEvent.DataEventID,
PluginID = dataEvent.DataOwnerID,
TimeStamp = dataEvent.DataTimeStamp,
DataEventKeyID = attribute.DataEventKeyID,
ValueString = attribute.ValueString,
ValueDecimal = attribute.ValueDecimal
};
// list of some ids that we need to confirm exist in the initial query before the final query
var someSetOfIDs = new List<int>() {1, 2, 3, 4, 5};
// This is the local collection thats filtering out some results before I rebuild the entire result set in the final query
// If you comment this line out, the finalQuery will execute just fine.
// with this in place, the "Queries with local collections are not supported" error will come about.
initialQuery = initialQuery.Where(x => x.DataEventKeyID == 1 && someSetOfIDs.Contains((int) x.ValueDecimal));
// reusable query for the sub queries in the results -- not part of the problem, just part of the example
var attributeBaseQuery = from attribute in DataEventAttribute.GetByQueryExpression(context) select attribute;
// Builds the final result With the IDs from the initial query
// the group by is to remove any duplicates that may be in the collection.
// the select key is getting the ID that i needed
// the select ID is the ID of the first item that was grouped.
// the contains compares the local dataEvent object with the ID table (checking to see if it exists)
// the result is just an example of one item I can be pulling out of the database with the new type
var finalQuery = from dataEvent in DataEvent.GetByQueryExpression(context)
where initialQuery.GroupBy(x => x).Select(x => x.Key).Select(x => x.ID).Contains(dataEvent.DataEventID)
select new
{
BasicData =
attributeBaseQuery.Where(
attrValue =>
attrValue.DataEventID == dataEvent.DataEventID &&
attrValue.DataEventKeyID == (short) DataEventTypesEnum.BasicData).FirstOrDefault().
ValueString
};
var finalResult = finalQuery.Take(100).ToList();
我发现的一个解决方案是在 finalQuery 中的 .Select(x => x.ID) 之后执行 .ToList(),但副作用有两个负面影响。第一,它首先运行该查询,并从数据库中获取 ID。然后它必须将这些结果作为参数传递回 sql 服务器作为 finalQuery。第二个主要(显示停止)是,如果 .ToList() 有很多结果,SQL 服务器会抛出一些奇怪的错误消息,并且 Google 搜索显示有很多参数被传递(这是有道理的,因为参数计数可能在 10 到 100 之间)。
也就是说,我试图弄清楚如何构建一个可以动态调整条件的查询,然后使用与满足子查询条件的 ID 匹配的所有属性重建我的结果集。通过工作室在 SQL Server 中,这工作正常,但收集问题让我陷入困境。
我尝试了许多不同的方法,但似乎重现此问题的唯一方法是使用本地集合的查询,然后将该查询用作另一个查询的一部分,该查询使用第一个查询过滤结果。
有什么想法可以做到这一点吗?
Screen shot show you know I'm not crazy.
提前感谢您的帮助
【问题讨论】:
标签: c# linq-to-sql