在Xamarin.Forms应用中使用realm-dotnet的反向链接功能

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

我目前的雇主正在使用Xamarin.Forms和后端的Asp.net mvc开发移动应用程序。我建议在移动应用程序中使用领域。我的经理希望在将POC(Proof of concept)功能用于领域之前先将其与backlink应用结合使用。我正在GitHub上进行POC。该文档非常有限,并且realm-dotnet的GitHub存储库中没有很好的sample。我完成了项目。但是无法实现backlink。我开发的示例应用程序允许用户在第一页中创建assignees(employees)。用户可以使用context menu删除或编辑员工。当用户单击员工名称时,应用程序导航到该特定员工的ToDoListPage。用户可以在此处创建ToDoItems。在此ToDoList页面上,我想显示仅assignedemployee的ToDoItems。模型如下:

public class Assignee : RealmObject
{
    public Assignee()
    {
        ToDoItems = Enumerable.Empty<ToDoItem>().AsQueryable();
    }
    [PrimaryKey]
    public string Id { get; set; } = Guid.NewGuid().ToString();
    public string Name { get; set; }
    public string Role { get; set; }
    [Backlink(nameof(ToDoItem.Employee))]
    public IQueryable<ToDoItem> ToDoItems { get; }
}

public class ToDoItem : RealmObject
{
    [PrimaryKey]
    public string Id { get; set; } = Guid.NewGuid().ToString();
    public string Name { get; set; }
    public string Description { get; set; }
    public bool Done { get; set; }
    public Assignee Employee { get; set; }
}

我正在向每个待办事项添加员工:

Item.Employee = Employee;
_realm.Add(Item);

现在我想访问员工的ToDoItems:

Items = _realm.All<Assignee>().Where(x => x.Id == EmployeeId).FirstOrDefault().ToDoItems;

但是这不起作用。如果有人可以通过在示例应用程序中编写代码或在回复中编写正确的代码来帮助我,我将不胜感激。

谢谢

xamarin.forms realm
1个回答
0
投票

首先,Realm .NET当前不支持遍历属性(x.Employee.Id)。因此,当我启动应用程序并尝试转到ToDoListPage时,该应用程序将崩溃,但例外:

Equal运算符的左侧必须是对Realm中持久属性的直接访问

Realm支持对象比较,因此我们可以这样解决:

var employee = _realm.Find<Assignee>(EmployeeId);
Items = _realm.All<ToDoItem>().Where(x => x.Employee == employee);

其次,您的代码中的所有内容看起来都很好,所以我更深入地研究了一下为什么它不起作用。问题是,当我们尝试使用上述代码获取所有项目时,EmployeeId参数为null。由于EmployeeId正在填充[[after,因此已经触发了加载逻辑,因此我们不需要将数据加载到ctor中。因此,您可以删除此代码。

最后,由于您不会在ctor中加载数据,而是在SetValues方法中加载数据,因此UI需要知道在更新数据后要重绘的内容。因此,您也需要将集合标记为Reactive

[Reactive] public IEnumerable<ToDoItem> Items { get; set; }

然后,您需要更改SetValues方法以使用对象比较,而不是遍历:

async Task SetValues() { Employee = _realm.Find<Assignee>(EmployeeId); Title = Employee.Name; Items = _realm.All<ToDoItem>().Where(x => x.Employee == Employee); }

总结起来-您不需要尝试将数据加载到ctor中,因为您不知道何时设置EmployeeId。您已经在跟踪属性何时更改,并且只需在SetValues命令中更改表达式谓词即可。
© www.soinside.com 2019 - 2024. All rights reserved.