realm / realm-dotnet

Realm is a mobile database: a replacement for SQLite & ORMs
https://realm.io
Apache License 2.0
1.25k stars 165 forks source link

Failed to load IList<int> from Realm database on a UWP project #1780

Closed hamz250 closed 3 years ago

hamz250 commented 6 years ago

Goals

I m facing a issue when trying read an IList from Realm while it works perfect when it is an IList

Expected Results

Reading and using a simple IList from realm.

Actual Results

groups = Count = Evaluation of method Realms.RealmCollectionBase`1[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].get_Count requires calling method System.RuntimeTypeHandle.ToEETypePtr, which cannot be call...

Steps to Reproduce

Buil a release version of the project wih .Net native compile.

Code Sample

List documents = realm.All().ToList().Select(t => new Document(t)).ToList();

While Document is : public class Document : RealmObject, ILang, IEquatable, IWSData { [PrimaryKey] public int id { get; set; } public string name { get; set; } public string lang { get; set; } public string summary { get; set; } public string date { get; set; } public bool? document_dissociable { get; set; } public bool can_be_added_to_cart { get; set; } public int order_id { get; set; } [Ignored] public DocumentType type { get; set; } [JsonIgnore] public string documentType { get; set; } public string file_url { get; set; } public string checkSum { get; set; } public IList medias_id { get; } public int revision { get; set; } public IList groups { get; } public string index_file_path { get; set; } public IList references_filter { get; } public IList keywords { get; } public IList parent { get;} public bool? is_shareable { get; set; } public string file_url_hd { get; set; } public string file_url_thumbnail { get; set; } public string checkSum_hd { get; set; } public bool is_opened { get; set; } public bool is_new { get; set; } public bool is_editable { get; set; } [Ignored] public DocumentFileType file_type { get; set; } = DocumentFileType.UNKNOWN; [JsonIgnore] public string documentFileType { get; set; }

    [JsonIgnore]
    public bool HasHd => file_url_hd != null;
    public bool is_listed_in_library { get; set; }
    public Document()
    {
    }
    public Document(Document document)
    {
        this.id = document.id;
        this.name = document.name;
        this.lang = document.lang;
        this.summary = document.summary;
        this.date = document.date;
        this.document_dissociable = document.document_dissociable;
        this.can_be_added_to_cart = document.can_be_added_to_cart;
        this.order_id = document.order_id;
        this.type = document.type;
        this.documentType = document.documentType;
        this.file_url = document.file_url;
        this.checkSum = document.checkSum;
        this.medias_id = document.medias_id;
        this.revision = document.revision;
        this.groups = document.groups;
        this.index_file_path = document.index_file_path;
        this.references_filter = document.references_filter;
        this.keywords = document.keywords;
        this.parent = document.parent.Select(p => new Parent(p)).ToList(); 
        this.is_shareable = document.is_shareable;
        this.file_url_hd = document.file_url_hd;
        this.file_url_thumbnail = document.file_url_thumbnail;
        this.checkSum_hd = document.checkSum_hd;
        this.is_opened = document.is_opened;
        this.is_new = document.is_new;
        this.is_editable = document.is_editable;
        this.file_type = document.file_type;
        this.documentFileType = document.documentFileType;
        this.is_listed_in_library = document.is_listed_in_library;
    }

}

Version of Realm and Tooling

nirinchev commented 6 years ago

Please share the full exception and stack trace that you get.

hamz250 commented 6 years ago

@nirinchev :

at McgInterop.realm_wrappers.get_primitive__0(ResultsHandle results, IntPtr link_ndx, PrimitiveValue& value, NativeException& ex) in c:\Users\hbouzidi\Documents\Workspace\Repo\Windows\migration\New SalesApp Project (code migration)\SalesApp\SalesApps\obj\x86\Release\ilc\intermediate\SalesApps.McgInterop\PInvoke.g.cs:line 561
   at Realms.ListHandle.GetPrimitiveAtIndexCore(IntPtr index, PrimitiveValue& result, NativeException& nativeException)
   at Realms.CollectionHandleBase.GetPrimitiveAtIndex(Int32 index, PropertyType type)
   at Realms.RealmCollectionBase`1.get_Item(Int32 index)
   at Realms.RealmCollectionBase`1.Enumerator.System.Collections.IEnumerator.get_Current()
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   at SalesApp.Core.Services.UIService.<>c__DisplayClass10_0.<navigateTo>b__0() in C:\Users\hbouzidi\Documents\Workspace\Repo\Windows\migration\New SalesApp Project (code migration)\SalesApp\SalesApp.Core\Services\UIService.cs:line 84
   at System.Action`1.Invoke(T obj)
   at McgInterop.ReverseComSharedStubs.Proc_(Object __this, IntPtr __methodPtr)
nirinchev commented 6 years ago

This doesn't include the exception message that you posted truncated in your original message. Particularly, I'm interested in the entirety of evaluation of method ... requires ...

hamz250 commented 6 years ago

It does not give me details as you can see at this screenshot : https://ibb.co/iT9SFf For all Ilist object Im getting the Evaluation of method Realms.RealmCollectionBase`1[[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].get_Count requires calling method System.RuntimeTypeHandle.ToEETypePtr, which cannot be call... But it's only for release with .Net compile config otherwise it works correcty. You can also notice that the IList which extends RealmObject is working fine.

hamz250 commented 6 years ago

Finally the solution was to create a RelmInt class & RealmString Classes and using them instead of primitive int and string types.

charlesroddie commented 4 years ago

UWP release mode when using IList<int>, IList<double>, etc., in mapped fields of RealmObject classes:

MCG warnings:

MCG : warning MCG0001: [MarshalAs(UnmanagedType=(Default), ElementType=(Default))] with type 'Realms.Native.PrimitiveValue' is not supported.This signature is located on 'System.Void Realms.ResultsHandle.NativeMethods.get_primitive(Realms.ResultsHandle, System.IntPtr, Realms.Native.PrimitiveValue, Realms.NativeException)'.
MCG : warning MCG0001: [MarshalAs(UnmanagedType=(Default), ElementType=(Default))] with type 'Realms.Native.PrimitiveValue' is not supported.This signature is located on 'System.Void Realms.ListHandle.NativeMethods.get_primitive(Realms.ListHandle, System.IntPtr, Realms.Native.PrimitiveValue, Realms.NativeException)'.

Runtime exception:

System.Runtime.InteropServices.MarshalDirectiveException
  HResult=0x80131535
  Message=Incompatible MarshalAs detected in parameter named 'value'. Please refer to MCG's warning message for more information.
  Source=<Cannot evaluate the exception source>
  StackTrace: <Cannot evaluate the exception stack trace>

Workaround: serialize the IList<int> to byte[] or string or create a RealmObject wrapper around int.

FoggyFinder commented 4 years ago

Some additional info:

The issue, as it was mention above, with parameter value here and here

MCVE:

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();

            Realm.DeleteRealm(RealmConfiguration.DefaultConfiguration);
            var realm = Realm.GetInstance();
            realm.Write(() =>
            {
                realm.Add(new SomeClass
                {
                    Data = { 1, 2, 3 }
                });
            });
            lbl.Text = string.Join(",", realm.Find<SomeClass>(0).Data);
        }
    }

    public class SomeClass : RealmObject
    {
        [PrimaryKey]
        public int Id { get; set; }
        public IList<double> Data { get; }
    }

MCVE project is attached

XFAppMCVE.zip

nirinchev commented 3 years ago

This was fixed in https://github.com/realm/realm-dotnet/pull/2170.