合并多个realm查询结果.net

Combine multiple realm query results .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 时,应用程序就会崩溃,似乎是一个 Whosebug 异常。

我首先想到解决这个问题是将查询分成块然后合并结果,但是 ConcatUnion 方法不适用于这些领域 IQueryables,那么,我还能如何合并这样的分块结果呢?或者还有其他解决方法吗?

我不能只将结果转换为列表或其他东西然后合并,我必须 return 领域对象作为 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)工作过,通常在某人的低级引擎之上。 (由 Realm 的 real 向导提供的 c-tree Plus ISAM 引擎或 C++ 核心)。

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

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

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

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

例如:您的 OneLetter table 将有一个 a 的条目,该条目使用与主要 Words 中所有匹配词的 one-to-many 关系table.

这将非常快速地交付Ilist您可以迭代匹配的词。

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

SQL 服务器的 SQL 提供程序可以处理包含的项目数超过一个查询中 SQL 参数的最大数量限制,即 2100。

此示例有效:

var ids = new List<int>();
for (int i = 0; i < 10000; i++)
{
    ids.Add(i);
}

var testQuery = dbContext.Entity.Where(x => ids.Contains(x.Id)).ToList();

这意味着,您可以尝试重写您的方法以使用 ids.Contains(x.Id)

如何做到这一点的一个例子是

更新:抱歉没有提到这是 Realm 的,但也许它仍然值得一试。