Linq in monotouch(在设备上调试)

时间:2013-01-14 19:17:09

标签: linq xamarin.ios jit aot azure-mobile-services

我正在尝试运行Windows Azure移动服务查询(使用SDK的xamarins monotouch fork)。

此代码在模拟器上运行正常,但它在设备上爆炸:

this.table.Where (a => a.Sequence == sequence).Where (a => a.Week == week).ToListAsync()
                .ContinueWith (t =>
            {
                this.items = t.Result;
                this.tableView.ReloadData ();
                IsUpdating = false;
            }, scheduler);

我得到的错误是:

  

调用目标抛出了异常。 --->   System.Exception:尝试JIT编译方法   运行时'System.Linq.jvm.Runner:GetDelegate()'   --aot只。

我设法做的唯一一件事就是去除where条件。 这很好用,除了我(显然)没有根据需要过滤结果。

我应该如何重写代码以使其在实际的iOS设备上运行?

更新: table是* IMobileServiceTable<类型的类变量。活动> *

周和序列都是 int 类型。

活动是POCO类。

    public class Activity
{
        public int ID {
            get;
            set;
        }
        public string Name {
            get;
            set;
        }

        public int CaloricRequirementMin {
            get;
            set;
        }

        public int CaloricRequirementMax {
            get;
            set;
        }

        public string Difficulty {
            get;
            set;
        }

        public int PlanId {get;set;}

        public string Type {
            get;
            set;
        }

        public int Sequence {
            get;
            set;
        }
        public int Week {
            get;
            set;
        }

        public int SubscriptionActivityId {
            get;
            set;
        }
}

我已仔细检查以确保这些都已填充。

它在模拟器上完美无缺。

2 个答案:

答案 0 :(得分:1)

MonoTouch Ahead Of Time(AOT)编译器的重点是避免Apple不允许在iOS中编译的问题。这是几个安全策略之一,以及签名的可执行文件,应用程序审查,沙箱等。不幸的是,某些LINQ表达式需要JIT编译,因此无法在设备上运行。

所有LINQ表达式都可以转换为非LINQ,通常是迭代的代码。在转换为迭代之前,您可以考虑一些可能有效的LINQ替代方法,例如Any()表达式。

答案 1 :(得分:1)

最后,我不得不修改我的代码,使用ReadAsync和字符串查询而不是linq表达式。

this.table.ReadAsync(query)
                .ContinueWith (t =>
            {
                    items = (from item in t.Result.GetArray()
                             let act = item.GetObject()
                    select new Activity{
                        ID= Convert.ToInt32(act.GetNamedNumber("id")),
                        Name= act.GetNamedString("Name"),
                        SubscriptionActivityId = act.ContainsKey("SubscriptionActivityId") ? Convert.ToInt32(act.GetNamedNumber("SubscriptionActivityId")) : 0
                    }).ToList();


                    this.tableView.ReloadData ();
                IsUpdating = false;
            }, scheduler);