realm.xamarin抛出错误:方法'包含'不支持。同为“任意” [英] realm.xamarin throws error: The method 'Contains' is not supported. same for 'Any'

查看:389
本文介绍了realm.xamarin抛出错误:方法'包含'不支持。同为“任意”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写这要求凡在像realm.xamarin LINQ查询子句的查询。下面是我想查询:

  VAR IdsToMatch = observations.Select(X => x.Id)
从D VAR的结果=在realm.All<&观察GT;()其中IdsToMatch.Any(p =指p == d.Id)选择D组;



也试图与包含

  VAR结果从D =在realm.All<&观察GT;()其中IdsToMatch.Contains(d.Id)选择D组; 



不过,这将引发错误:

 的方法'包含'不支持
的方法'任何'不支持

什么是该解决方案



编辑:



下面是错误的堆栈跟踪:




未处理的异常:
06-07 15:04:55.097我/ MonoDroid的(24526):System.NotSupportedException:该法'任何'不支持
06-07 15:04:55.097 I / MonoDroid的(24526):在Realms.RealmResultsVisitor.VisitMethodCall(System.Linq.Expressions。 MethodCallExpression M)[0x00596]中:0
06-07 15:04:55.097 I / MonoDroid的(24526):在Realms.ExpressionVisitor.Visit(System.Linq.Expressions.Expression EXP)[0x000ec]中:0
06-07 15:04:55.097 I / MonoDroid的(24526):在Realms.RealmResultsVisitor.VisitMethodCall(System.Linq.Expressions.MethodCallExpression米)[0x0006a]中:0
06-07 15: 04:55.097 I / MonoDroid的(24526):在Realms.ExpressionVisitor.Visit(System.Linq.Expressions.Expression EXP)[0x000ec]中:0
06-07 15:04:55.097 I / MonoDroid的(24526) :在Realms.RealmResults 1 [T] .CreateResultsHandle()[0x00037]上述<文件名不明> 0
06-07 15:04:55.097 I / MonoDroid的(24526):在Realms.RealmResults
1 [T] .get_ResultsHandle()[0x0000d]中:0
06-07 15:04:55.097 I / MonoDroid的(24526):在Realms.RealmResults 1 [T] .GetEnumerator()[0x00000]上述<文件名不明> 0
06-07 15:04:55.097 I / MonoDroid的(24526):在System.Collections.Generic.List
1[T]..ctor(IEnumerable的 1集)[0x00073]在/用户/建设者/数据/车道/ 3053 / a94a03b5 /来源/单声道/外部/ referencesource / mscorlib程序/system/collections/generic/list.cs:104
06-07 15:04:55.098 I / MonoDroid的(24526):在System.Linq.Enumerable.ToList [TSource](IEnumerable的
1源)[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 + LT;> 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.Task 1 [TResult] .InnerInvoke ()[0x00012]在/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):在System.Threading.Tasks.Task.Execute()[0x00016]在/用户/建设者/数据/车道/ 3053 / a94a03b5 /来源/单声道/外部/ referencesource / mscorlib程序/系统/线程/任务/ Task.cs:2523
06-07 15:04:55.098 I / MonoDroid的(24526):---从以前的位置堆栈跟踪,其中引发异常---
06的结束-07 15:04:55.098 I / MonoDroid的(24526):在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()[0x0000c]在/用户/建设者/数据/车道/ 3053 / a94a03b5 /来源/单声道/外部/ referencesource /mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143
06-07 15:04:55.098 I / MonoDroid的(24526):在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks。任务task)[0x00047]在/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):在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)0x0002e]在/用户/建设者/数据/车道/ 3053 / a94a03b5 /来源/单/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:170
06-07 15:04:55.098 I / MonoDroid的(24526):在System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(系统。 Threading.Tasks.Task任务)[0x0000b]在/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):在System.Runtime.CompilerServices.TaskAwaiter
1 [TResult] .GetResult()[0x00000]在/用户/建设者/数据/车道/ 3053 / a94a03b5 /来源/单声道/外部/ referencesource / mscorlib程序/系统/运行/ compilerservices / TaskAwaiter.cs:372




编辑2:

  VAR IdsToMatch = observations.Select(X => x.Id)
变种结果从D =在realm.All<&观察GT;()其中IdsToMatch.Any(P =指p == d.Id)选择D组;



尝试: VAR IdsToMatch = observations.Select(X => X。 ID).AsQueryable()
按的 https://github.com/realm/realm-dotnet/blob/7187390529201ba843cd105fc6e3e11acb0c6217/Realm.Shared/linq/RealmResultsVisitor.cs#L121 它说

 内部覆盖表达VisitMethodCall(MethodCallExpression米)
{
如果(m.Method.DeclaringType == typeof运算(可查询)) {...

但没有工作过。


< DIV CLASS =h2_lin>解决方案

OK,这是一个很大的乐趣。答案(对于现在)是建立一个LINQ 表达式树



服务器支持LINQ - 我们解析表达式树(OK,有些位失踪,但基本在那里,我们经常提高 - 我们的添加包含)。



所以,你需要建立在运行时完全任意查询表达式任何时候都可以使用LINQ的权力这样做。



下面的例子可能会显得有点复杂,但问题是,它使用了标准表达式树所以你可以用它建立这些树木任何其他代码。

 类HasIntKey:RealmObject {
公众诠释用户键{搞定;组; }
}


私人无效FindingManyMatches()使用
{
(VAR theRealm = Realm.GetInstance(TestingManyKeys.realm)){
//创建一些示例数据
theRealm.Write(()=> {
的for(int i = 1; I< 10000;我++){
VAR OBJ = theRealm .CreateObject< HasIntKey>();
obj.UserKey = I;
}
});
VAR allInts = theRealm.All< HasIntKey>();
Console.WriteLine($创建{allInts.Count()}对象);

变种idsToMatch =新[] {42,1003,400,57,6009};

//技术如何寻找很多比赛
//使用表达式树来动态地构建LINQ声明
//看到https://msdn.microsoft.com/ EN-US /库/ mt654267.aspx
ParameterExpression PE = Expression.Parameter(typeof运算(HasIntKey),p);

//建立像的表达式:
// allInts.Where(p值=> p.UserKey == idsToMatch [0] || p.UserKey == idsToMatch [1]。 ..);
表达chainedByOr = NULL;使用==
//左边将是我们留给= Expression.Property(PE的typeof(HasIntKey).GetProperty(用户键))循环
表达添加的每个条款是相同的;
的foreach(在idsToMatch INT ANID){
//创建一个代表表达式'p.UserKey == idsToMatch [N]'表达式树。
表达权= Expression.Constant(ANID);
表达anotherEqual = Expression.Equal(左,右);
如果(chainedByOr == NULL)
chainedByOr = anotherEqual;
,否则
chainedByOr = Expression.OrElse(chainedByOr,anotherEqual);
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof运算(可查询),
去哪儿,
新型[] {} allInts.ElementType,
allInts.Expression,
Expression.Lambda<&Func键LT; HasIntKey,布尔>>(chainedByOr,新ParameterExpression [] {} PE));

//创建一个从表达式树的可执行查询。
&IQueryable的LT; HasIntKey>结果= allInts.Provider.CreateQuery< HasIntKey>(whereCallExpression);

//现在我们有我们的结果显示一些细节!
Console.WriteLine($找到{results.Count()}对象);

//枚举的结果。
的foreach(HasIntKey anObj在结果)
Console.WriteLine($找到键{} anObj.UserKey);
}
}


i am writing a query which required 'WHERE IN' like clause in realm.xamarin linq query. below is the query i tried:

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

also tried this with Contains:

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

but this throws error:

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

What is the solution for this?

EDIT :

here is the stack trace for the error:

UNHANDLED EXCEPTION: 06-07 15:04:55.097 I/MonoDroid(24526): System.NotSupportedException: The method 'Any' is not supported 06-07 15:04:55.097 I/MonoDroid(24526): at 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): at Realms.ExpressionVisitor.Visit (System.Linq.Expressions.Expression exp) [0x000ec] in :0 06-07 15:04:55.097 I/MonoDroid(24526): at Realms.RealmResults1[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): at 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 source) [0x00011] in /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): at VHS.MobileApp.Mediq.DataAccess.ObservationDatabase+<>c__DisplayClass13.b__8 () [0x00147] in d:\rwagh\mediq\Code\VHS.MobileApp.Mediq.DataAccess\ObservationDatabase.cs:65 06-07 15:04:55.098 I/MonoDroid(24526): at 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] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:372

EDIT 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;

tried: var IdsToMatch = observations.Select(x => x.Id).AsQueryable() as per https://github.com/realm/realm-dotnet/blob/7187390529201ba843cd105fc6e3e11acb0c6217/Realm.Shared/linq/RealmResultsVisitor.cs#L121 which says

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

but that didn't work too.

解决方案

OK, that was a lot of fun. The answer (for right now) is to build a LINQ Expression Tree.

Realm supports LINQ - we parse the Expression Tree (OK, some bits are missing but the basics are there and we're improving regularly - we will add Contains).

So, any time you need to build up a completely arbitrary query expression at runtime you can do so with the power of LINQ.

The example below may appear a bit complicated but the point is that it uses a standard Expression tree so you can use any other code which builds such trees.

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<HasIntKey> ();
                obj.UserKey = i;
            }
        });
        var allInts = theRealm.All<HasIntKey>();
        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<Func<HasIntKey, bool>>(chainedByOr, new ParameterExpression[] { pe }));

        // Create an executable query from the expression tree.
        IQueryable<HasIntKey> results = allInts.Provider.CreateQuery<HasIntKey>(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}");
    }
}

这篇关于realm.xamarin抛出错误:方法'包含'不支持。同为“任意”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆