Uploaded image for project: 'Realm .NET SDK'
  1. Realm .NET SDK
  2. RNET-620

[Unity][Bug] string.Contains() throws NotSupportedException in Unity 2021.2

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • Q3-23FY
    • Affects Version/s: None
    • Component/s: None

      Realm Version: 10.7.1
      Unity Version: 2021.2.5f1
      Client OS: Windows 10 Pro 21H1 19043.1348

      I recently upgraded my Unity version from 2020.3 to 2021.2. Since the update, calling string.Contains() in a realm query throws a NotSupportedException. With Unity 2020.3 results get returned as expected and no exception is thrown. My model looks like this:

      Unable to find source-code formatter for language: cs. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      public class Tag : RealmObject
      {
          [PrimaryKey]
          public int Uid { get; set; }
          [Required]
          public string Name { get; set; }
      }
      

      and the class executing the query like this:

      Unable to find source-code formatter for language: cs. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      using Realms;
      using System.IO;
      using System.Linq;
      using UnityEngine;
      
      public class RealmExample : MonoBehaviour
      {
          private static Realm realm;
      
          private void Awake()
          {
              RealmConfiguration config = new(Path.Combine(Application.dataPath, "database.realm"))
              {
                  IsReadOnly = true,
                  Schema = new[]
                  {
                      typeof(Tag),
                  },
                  SchemaVersion = 11ul
              };
              realm = Realm.GetInstance(config);
          }
      
          [ContextMenu("QueryTags")]
          public void QueryTags()
          {
              string substring = "T";
              IQueryable<Tag> tags = realm.All<Tag>()
                                          // The line below is the one causing the exception
                                          .Where(t => t.Name.Contains(substring, System.StringComparison.OrdinalIgnoreCase));
      
              foreach (var t in tags)
              {
                  print(t.Name);
              }
          }
      }
      

      I receive the following exception:

      NotSupportedException: The left-hand side of the Call operator must be a direct access to a persisted property in Realm.
      Unable to process 'value(RealmExample+<>c__DisplayClass2_0).substring'.
      Realms.RealmResultsVisitor.GetColumnName (System.Linq.Expressions.MemberExpression memberExpression, System.Nullable`1[T] parentType) (at <5ee71c2d3038455ca732a3febcca3879>:0)
      Realms.RealmResultsVisitor.VisitMethodCall (System.Linq.Expressions.MethodCallExpression node) (at <5ee71c2d3038455ca732a3febcca3879>:0)
      System.Linq.Expressions.MethodCallExpression.Accept (System.Linq.Expressions.ExpressionVisitor visitor) (at <61774763be294c9f8e2c781f10819224>:0)
      System.Linq.Expressions.ExpressionVisitor.Visit (System.Linq.Expressions.Expression node) (at <61774763be294c9f8e2c781f10819224>:0)
      Realms.RealmResultsVisitor.VisitMethodCall (System.Linq.Expressions.MethodCallExpression node) (at <5ee71c2d3038455ca732a3febcca3879>:0)
      System.Linq.Expressions.MethodCallExpression.Accept (System.Linq.Expressions.ExpressionVisitor visitor) (at <61774763be294c9f8e2c781f10819224>:0)
      System.Linq.Expressions.ExpressionVisitor.Visit (System.Linq.Expressions.Expression node) (at <61774763be294c9f8e2c781f10819224>:0)
      Realms.RealmResults`1[T].GetOrCreateHandle () (at <5ee71c2d3038455ca732a3febcca3879>:0)
      System.Lazy`1[T].ViaFactory (System.Threading.LazyThreadSafetyMode mode) (at <00c558282d074245ab3496e2d108079b>:0)
      System.Lazy`1[T].ExecutionAndPublication (System.LazyHelper executionAndPublication, System.Boolean useDefaultConstructor) (at <00c558282d074245ab3496e2d108079b>:0)
      System.Lazy`1[T].CreateValue () (at <00c558282d074245ab3496e2d108079b>:0)
      System.Lazy`1[T].get_Value () (at <00c558282d074245ab3496e2d108079b>:0)
      Realms.RealmCollectionBase`1+Enumerator[T]..ctor (Realms.RealmCollectionBase`1[T] parent) (at <5ee71c2d3038455ca732a3febcca3879>:0)
      Realms.RealmCollectionBase`1[T].GetEnumerator () (at <5ee71c2d3038455ca732a3febcca3879>:0)
      RealmExample.QueryTags () (at Assets/RealmExample.cs:32)
      

      My current workaround is to use Like() instead of Contains() like this

      Unable to find source-code formatter for language: cs. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      // Added the asterisk to match the behaviour of Contains()
      string substring = "*T*";
      IQueryable<Tag> tags = realm.All<Tag>()
                                  // This works fine
                                  .Where(t => t.Name.Like(substring, false));
      

            Assignee:
            nikola.irinchev@mongodb.com Nikola Irinchev
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: