结合多个境界查询结果.net

问题描述 投票:0回答:2

作为 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);
        }

只要我输入少于2 -3千的id就能正常工作 当我输入更多的id时 应用程序就会崩溃并出现堆栈溢出异常

我最初想到的解决方法是把查询分成几块,之后再把结果组合起来,但是在 ConcatUnion 方法在这些境界上不起作用 IQueryables那么,我还能如何合并这样的分块结果呢?或者有什么其他的变通方法吗?

我不能直接把结果转换成List之类的然后合并,我必须把境界对象返回为 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# optimization realm expression-trees
2个回答
1
投票

我是... 一个数据库专家,只是在不同级别(inc Realm)工作过,通常是在别人的低级引擎之上。(c-tree Plus ISAM引擎或由C++核心的? 真正 Realm的向导们)。)

我的第一印象是,你的数据大多是静态数据,所以这是一个相当经典的问题,你希望在前期生成一个更好的索引。

我认为你可以用Realm建立这样一个索引,但要多用一些应用逻辑。

这听起来有点像一个倒置索引问题,如 这个问题.

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

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

这将交付一个非常快的 Ilist 你可以对匹配的单词进行迭代。

然后你可以翻到你的 Contains 3个字母或以上的方法。


0
投票

SQL Server的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).

如何做到这一点的例子是 在这个职位上.

更新:抱歉没有提到这是境界的,但也许还是值得一试。

© www.soinside.com 2019 - 2024. All rights reserved.