【发布时间】:2016-06-07 09:25:03
【问题描述】:
我正在编写一个查询,它需要在 realm.xamarin linq 查询中使用类似“WHERE IN”的子句。以下是我尝试过的查询:
var IdsToMatch = observations.Select(x => x.Id)
var results = from d in realm.All<Observations>() where IdsToMatch.Any(p => p == d.Id) select d;
也试过Contains:
var results = from d in realm.All<Observations>() where IdsToMatch.Contains(d.Id) select d;
但这会引发错误:
The method 'Contains' is not supported
The method 'Any' is not supported
解决办法是什么?
编辑:
这是错误的堆栈跟踪:
未处理的异常: 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): 在 Realms.ExpressionVisitor.Visit (System.Linq.Expressions.Expression exp) [0x000ec] in :0 06-07 15:04:55.097 I/MonoDroid(24526): 在 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): 在 Realms.RealmResults
1[T].CreateResultsHandle () [0x00037] in <filename unknown>:0 06-07 15:04:55.097 I/MonoDroid(24526): at Realms.RealmResults1[T].get_ResultsHandle () [0x0000d] in :0 06-07 15:04:55.097 I/MonoDroid(24526): 在 Realms.RealmResults1[T].GetEnumerator () [0x00000] in <filename unknown>:0 06-07 15:04:55.097 I/MonoDroid(24526): at System.Collections.Generic.List1[T]..ctor (IEnumerable1 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] (IEnumerable1 源) [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): 在 VHS.MobileApp.Mediq.DataAccess.ObservationDatabase+c__DisplayClass13.b__8 () [0x00147] 在 d:\rwagh\mediq\Code\VHS.MobileApp.Mediq .DataAccess\ObservationDatabase.cs:65 06-07 15:04:55.098 I/MonoDroid(24526): 在 System.Threading.Tasks.Task1[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.TaskAwaiter1[TResult].GetResult () [0x00000] 在 /Users/builder/data/lanes/3053/a94a03b5 /source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:372
编辑 2:
var IdsToMatch = observations.Select(x => x.Id)
var results = from d in realm.All<Observations>() 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)) { ...
但这也没有用。
【问题讨论】:
-
我的猜测是表达式访问者不支持您正在使用的外部枚举的那些方法。您要么必须: - 获取不带 Where 子句的所有记录(使用 .ToLisT()),然后在这些内存结果中使用 Contains(可能不是一个好主意),要么 - 循环遍历可枚举和查询中的每个 Id对于那些ID一个接一个。虽然。你试过
p => p.Id.In(IdsToMatch) -
@AndyJames "Id" 是原始类型(Int/String),因此 "In" 不是可用的函数。
-
很多框架都提供
In作为通用扩展方法,所以它对object有效。但是,如果您没有在任何地方定义它,尤其是在 Realms 中,表达式访问者将不知道那是什么并且无论如何都会死去。在这种情况下可能不是一个选择。 -
我已经为此github.com/realm/realm-dotnet/issues/604 添加了一个领域问题,但请提供更多信息,因为从您的示例中并不能完全清楚您在做什么。 IdsToMatch 只是一个 ID 列表吗?
-
我怀疑您正在尝试用 SQL 术语执行类似于 IN 查询的操作,请参阅 stackoverflow.com/questions/2334327/…
标签: c# linq xamarin realm realm-net