realm.xamarin抛出错误:不支持方法’Contains’。 ‘任意’相同

我正在编写一个在realm.xamarin linq查询中需要’WHERE IN’like子句的查询。 下面是我试过的查询:

var IdsToMatch = observations.Select(x => x.Id) var results = from d in realm.All() where IdsToMatch.Any(p => p == d.Id) select d; 

还尝试使用Contains

 var results = from d in realm.All() where IdsToMatch.Contains(d.Id) select d; 

但这会引发错误:

 The method 'Contains' is not supported The method 'Any' is not supported 

这是什么解决方案?

编辑:

这是错误的堆栈跟踪:

UNHANDLED EXCEPTION:06-07 15:04:55.097 I / MonoDroid(24526):System.NotSupportedException:不支持方法’Any’06-07 15:04:55.097 I / MonoDroid(24526):在Realms.RealmResultsVisitor。 VisitMethodCall(System.Linq.Expressions.MethodCallExpression m)[0x00596] in:0 06-07 15:04:55.097 I / MonoDroid(24526):at Realms.ExpressionVisitor.Visit(System.Linq.Expressions.Expression exp)[0x000ec ] in:0 06-07 15:04:55.097 I / MonoDroid(24526):at Realms.RealmResultsVisitor.VisitMethodCall(System.Linq.Expressions.MethodCallExpression m)[0x0006a] in:0 06-07 15:04:55.097 I / MonoDroid(24526):在Realms.ExpressionVisitor.Visit(System.Linq.Expressions.Expression exp)[0x000ec] in:0 06-07 15:04:55.097 I / MonoDroid(24526):at Realms.RealmResults 1[T].CreateResultsHandle () [0x00037] in :0 06-07 15:04:55.097 I/MonoDroid(24526): at Realms.RealmResults 1 [T] .get_ResultsHandle()[0x0000d] in:0 06- 07 15:04:55.097 I / MonoDroid(24526):在Realms.RealmResults 1[T].GetEnumerator () [0x00000] in :0 06-07 15:04:55.097 I/MonoDroid(24526): at System.Collections.Generic.List 1[T].GetEnumerator () [0x00000] in :0 06-07 15:04:55.097 I/MonoDroid(24526): at System.Collections.Generic.List 1 [T] .. ctor(IEnumerable 1 collection) [0x00073] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/collections/generic/list.cs:104 06-07 15:04:55.098 I/MonoDroid(24526): at System.Linq.Enumerable.ToList[TSource] (IEnumerable 1 source)[0x00011]在/Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs: 835 06-07 15:04:55.098 I / MonoDroid(24526):在d:\ rwagh \ mediq \ Code \ VHS.MobileApp中的VHS.MobileApp.Mediq.DataAccess.ObservationDatabase + c__DisplayClass13.b__8()[0x00147]。 Mediq.DataAccess \ ObservationDatabase.cs:65 06-07 15:04:55.098 I / MonoDroid(24526): 1[TResult].InnerInvoke () [0x00012] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Future.cs:686 06-07 15:04:55.098 I/MonoDroid(24526): at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2523 06-07 15:04:55.098 I/MonoDroid(24526): --- End of stack trace from previous location where exception was thrown --- 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:201 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task 1[TResult].InnerInvoke () [0x00012] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Future.cs:686 06-07 15:04:55.098 I/MonoDroid(24526): at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2523 06-07 15:04:55.098 I/MonoDroid(24526): --- End of stack trace from previous location where exception was thrown --- 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:201 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter 1[TResult].InnerInvoke () [0x00012] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Future.cs:686 06-07 15:04:55.098 I/MonoDroid(24526): at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2523 06-07 15:04:55.098 I/MonoDroid(24526): --- End of stack trace from previous location where exception was thrown --- 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:201 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter 1[TResult].InnerInvoke () [0x00012] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Future.cs:686 06-07 15:04:55.098 I/MonoDroid(24526): at System.Threading.Tasks.Task.Execute () [0x00016] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/threading/Tasks/Task.cs:2523 06-07 15:04:55.098 I/MonoDroid(24526): --- End of stack trace from previous location where exception was thrown --- 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:201 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:142 06-07 15:04:55.098 I/MonoDroid(24526): at System.Runtime.CompilerServices.TaskAwaiter 1 [TResult] .GetResult()[0x00000] in /用户/助洗剂/数据/通道/ 3053 / a94a03b5 /源/单声道/外部/ referencesource / mscorlib程序/系统/运行/ compilerservices / TaskAwaiter.cs:372

编辑2:

 var IdsToMatch = observations.Select(x => x.Id) var results = from d in realm.All() where IdsToMatch.Any(p => p == d.Id) select d; 

尝试: var IdsToMatch = observations.Select(x => x.Id).AsQueryable()根据https://github.com/realm/realm-dotnet/blob/7187390529201ba843cd105fc6e3e11acb0c6217/Realm.Shared/linq/RealmResultsVisitor.cs# L121说

 internal override Expression VisitMethodCall(MethodCallExpression m) { if (m.Method.DeclaringType == typeof(Queryable)) { ... 

但那也行不通。

好的,这很有趣。 答案(目前)是构建LINQ 表达式树 。

Realm支持LINQ – 我们解析表达式树(好的,有些位丢失,但基础知识在那里,我们正在定期改进 – 我们添加Contains)。

因此,只要您需要在运行时构建完全任意的查询表达式,就可以使用LINQ的强大function。

下面的示例可能看起来有点复杂,但重点是它使用标准的表达式树,因此您可以使用任何其他构建此类树的代码。

 class HasIntKey : RealmObject { public int UserKey { get; set; } } private void FindingManyMatches() { using (var theRealm = Realm.GetInstance ("TestingManyKeys.realm")) { // create some sample data theRealm.Write (() => { for (int i = 1; i < 10000; i++) { var obj = theRealm.CreateObject (); obj.UserKey = i; } }); var allInts = theRealm.All(); Console.WriteLine ($"Created {allInts.Count()} objects"); var idsToMatch = new[] {42,1003,400,57, 6009}; // technique for how to search for many matches // use Expression Trees to dynamically build the LINQ statement // see https://msdn.microsoft.com/en-us/library/mt654267.aspx ParameterExpression pe = Expression.Parameter (typeof(HasIntKey), "p"); // building an expression like: // allInts.Where (p => p.UserKey == idsToMatch[0] || p.UserKey == idsToMatch[1]...); Expression chainedByOr = null; // left side of the == will be the same for each clause we add in the loop Expression left = Expression.Property(pe, typeof(HasIntKey).GetProperty("UserKey")); foreach (int anId in idsToMatch) { // Create an expression tree that represents the expression 'p.UserKey == idsToMatch[n]'. Expression right = Expression.Constant(anId); 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[] { allInts.ElementType }, allInts.Expression, Expression.Lambda>(chainedByOr, new ParameterExpression[] { pe })); // Create an executable query from the expression tree. IQueryable results = allInts.Provider.CreateQuery(whereCallExpression); // now we have our results, display some details! Console.WriteLine ($"Found {results.Count()} objects"); // Enumerate the results. foreach (HasIntKey anObj in results) Console.WriteLine($"Found key {anObj.UserKey}"); } } 

这是我的研究和调试超过1周。

我们再次面临这个问题:

 var result = from ppl in realm.All() where ppl.Name.Contains("John") select ppl; 

抛出exception: 不支持方法“包含”。

修复了什么:

 IEnumerable iAllPLL = realm.All(); var result = from ppl in iAllPLL where ppl.Name.Contains("John") select ppl; 

简单的猜想(或者有人可以解释一下):

  1. 直接在RealmResult上执行LINQ表达式将面临大问题。

  2. 实现 Enumerable 接口后LINQ表达式表现良好。