首页 > 解决方案 > 结合多个领域查询结果.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 异常。

解决这个问题的第一个想法是将查询分成块然后组合结果,但是ConcatandUnion方法在这些领域不起作用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,如果我传递大于该值的任何元素,它就会崩溃。

标签: c#optimizationrealmexpression-trees

解决方案


不是数据库专家,只是在不同级别(包括领域)工作过,通常是在某人的低级引擎之上。(Realm真正的向导提供的 c-tree Plus ISAM 引擎或 C++ 核心)。

我的第一印象是您拥有大部分静态数据,因此这是一个相当经典的问题,您希望预先生成更好的索引。

我认为您可以使用 Realm 构建这样的索引,但需要更多的应用程序逻辑。

这听起来有点像这个 SO question中的倒排索引问题。

对于映射到您的单词的所有单个和可能至少是双单词组合,您需要另一个链接到所有匹配单词的表。你可以用一个相当简单的循环来创建那些,从现有的单词中创建它们。

例如:您的OneLetter表将有一个条目,a该条目与主表中的所有匹配词使用一对多关系。Words

这将提供一个非常快的Ilist你可以迭代匹配的单词。

Contains然后你可以在 3 个字母或更多字母处转向你的方法。


推荐阅读