c# - 结合多个领域查询结果.net
问题描述
作为一个Contains
实现,我使用了由 Andy Dent编写的稍微调整的方法来查询我的领域数据库:
private IQueryable<Entry> FilterEntriesByIds(IQueryable<Entry> allEntries, int[] idsToMatch)
{
// Fancy way to invent Contains<>() for LINQ
ParameterExpression pe = Expression.Parameter(typeof(Entry), "Entry");
Expression chainedByOr = null;
Expression left = Expression.Property(pe, typeof(Entry).GetProperty("Id"));
for (int i = 0; i < idsToMatch.Count(); i++) {
Expression right = Expression.Constant(idsToMatch[i]);
Expression anotherEqual = Expression.Equal(left, right);
if (chainedByOr == null)
chainedByOr = anotherEqual;
else
chainedByOr = Expression.OrElse(chainedByOr, anotherEqual);
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { allEntries.ElementType },
allEntries.Expression,
Expression.Lambda<Func<Entry, bool>>(chainedByOr, new ParameterExpression[] { pe }));
return allEntries.Provider.CreateQuery<Entry>(whereCallExpression);
}
只要我传递的 id 少于 2-3K,这一切都可以正常工作,当我使用大量的 id 时,应用程序就会崩溃,似乎是 stackoverflow 异常。
解决这个问题的第一个想法是将查询分成块然后组合结果,但是Concat
andUnion
方法在这些领域不起作用IQueryables
,那么,我还能如何合并这样的分块结果呢?或者还有其他解决方法吗?
我不能只是将结果转换为列表或其他东西然后合并,我必须将领域对象返回为IQueryable<>
调用堆栈:
=================================================================
Native Crash Reporting
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
No native Android stacktrace (see debuggerd output).
=================================================================
Basic Fault Address Reporting
=================================================================
Memory around native instruction pointer (0x7c326075c8):0x7c326075b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x7c326075c8 fd 7b bb a9 fd 03 00 91 a0 0b 00 f9 10 0e 87 d2 .{..............
0x7c326075d8 10 d0 a7 f2 90 0f c0 f2 b0 0f 00 f9 10 00 9e d2 ................
0x7c326075e8 f0 d5 a9 f2 90 0f c0 f2 b0 13 00 f9 a0 a3 00 91 ................
=================================================================
Managed Stacktrace:
============================
=====================================
at Realms.QueryHandle:GroupBegin <0x00000>
at Realms.RealmResultsVisitor:VisitCombination <0x0007f>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.ExpressionVisitor:Visit <0x00087>
at Realms.RealmResultsVisitor:VisitCombination <0x000d7>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.ExpressionVisitor:Visit <0x00087>
at Realms.RealmResultsVisitor:VisitCombination <0x000d7>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.ExpressionVisitor:Visit <0x00087>
at Realms.RealmResultsVisitor:VisitCombination <0x000d7>
at Realms.RealmResultsVisitor:VisitBinary <0x003f7>
at System.Linq.Expressions.BinaryExpression:Accept <0x00073>
at System.Linq.Expressions.Ex
pressionVisitor:Visit <0x00087>
UPD
我找到了引发此错误的元素的确切数量:3939,如果我传递大于该值的任何元素,它就会崩溃。
解决方案
我不是数据库专家,只是在不同级别(包括领域)工作过,通常是在某人的低级引擎之上。(Realm真正的向导提供的 c-tree Plus ISAM 引擎或 C++ 核心)。
我的第一印象是您拥有大部分静态数据,因此这是一个相当经典的问题,您希望预先生成更好的索引。
我认为您可以使用 Realm 构建这样的索引,但需要更多的应用程序逻辑。
这听起来有点像这个 SO question中的倒排索引问题。
对于映射到您的单词的所有单个和可能至少是双单词组合,您需要另一个链接到所有匹配单词的表。你可以用一个相当简单的循环来创建那些,从现有的单词中创建它们。
例如:您的OneLetter
表将有一个条目,a
该条目与主表中的所有匹配词使用一对多关系。Words
这将提供一个非常快的Ilist
你可以迭代匹配的单词。
Contains
然后你可以在 3 个字母或更多字母处转向你的方法。
推荐阅读
- python - Python Telegram 如何在 MessageHandler 中捕获 ValueError
- sql - 如何在 GROUP BY 中选择其他行
- rtmp - 检测来自 ATEM Mini Pro ISO 的 RTMP 拉动
- reactjs - mapDispatchToProps 不工作。this.props.getCategories 不是函数
- javascript - 映射时,如何访问循环内的对象键?角
- ms-access - Access 组合具有相似值的不同列
- javascript - JqueryUI 拖放助手占位符位置
- javascript - 使用一个输入从 HTML 页面创建 JSON 文件
- javascript - 从数组中获取唯一的类别属性值
- vb.net - 从 BarCode Vb.Net 下方删除文本