【问题标题】:How to implement "get or create" query with Realm for Xamarin?如何使用 Realm for Xamarin 实现“获取或创建”查询?
【发布时间】:2016-08-31 15:45:59
【问题描述】:

考虑简单模型:

public class Session : RealmObject
{
    [ObjectId]
    public string UserId { get; set; }
    public string Token { get; set; }
}

如果Session 实例不存在,如何通过ID 或null 获取?

var realm = Realm.GetInstance ();
var q = realm.All<Session> ().Where ((x) => x.UserId = "1");
// This won't work if no session is saved:
// var session = q.First ();
// and this won't either
// var session = q.FirstOrDefault ();
// And this is mmm... kind of strange but it's working :)
var session = q.Count() > 0 ? q.First() : null;

那么,设计上应该怎么做呢?

【问题讨论】:

    标签: c# xamarin realm realm-net


    【解决方案1】:

    您希望做的是:

    var localSession = theRealm.All<Session>().FirstOrDefault((Session session) => session.UserId == "1");
    

    但是 FirstOrDefault/SingleOrDefault 尚不支持(截至0.77.2

    目前支持AnyFirstSingle (Current Linq Support):

    Any 样式上的 If/Else:

    Session session = null;
    var sessions = theRealm.All<Session>().Where((Session localSession) => localSession.UserId == "1");
    if (!sessions.Any())
        theRealm.Write(() =>
        {
            session = new Session() { UserId = "1", Token = "SO" };
        });
    else
        session = sessions.First();
    D.WriteLine($"{session?.UserId}:{session?.Token}");
    

    尝试/赶上InvalidOperationException:

    Session localSession = null;
    try
    {
        localSession = theRealm.All<Session>().First((Session session) => session.UserId == "1");
    }
    catch (InvalidOperationException error) when (error.Message == "Sequence contains no matching element")
    {
        theRealm.Write(() =>
        {
            localSession = new Session() { UserId = "1", Token = "SO" };
        });
    }
    D.WriteLine($"{localSession?.UserId}:{localSession?.Token}");
    

    【讨论】:

    • try / catch 方法对我来说似乎很自然,因为尚不支持 FirstOrDefault :) 但我不确定它是否是 .NET 编程的好习惯?
    • 如果您正在抛出并且经常这样做,那么 try/catch 的开销可能是一个问题,但是假设一旦您为用户创建了一个“会话”,例如每次应用运行一次,那么没有开销,因为自从您的会话存在以来,您永远不会展开堆栈......这取决于您的偏好,因为这确实是一个权宜之计,直到可以获得更好的 ling 支持。
    【解决方案2】:

    更新var localSession = theRealm.All&lt;Session&gt;().FirstOrDefault(session =&gt; session.UserId == "1"); 的支持已在 0.78.0 及更高版本中提供。

    原创

    我现在正在处理相关的Realm issue

    请在那里为您希望支持的特定场景添加 cmets。

    请注意,如果您想在 NuGet 正式发布之前尝试一些东西,我们现在也有 Nightly feed

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      • 2021-02-24
      • 2016-10-26
      • 1970-01-01
      • 1970-01-01
      • 2017-11-28
      • 2013-04-13
      相关资源
      最近更新 更多