Search code examples
c#genericsxamarinxamarin.formsrealm

generalize method to fetch and update data using generics in C#


i am trying to create generlize method to updateData when the record gets synced succesfully on the server using realm in xamarin.forms

private void updateContactData<T>(Realm realm, IList<T> dataList) where T : RealmObject , IMaster
    {

        realm.WriteAsync(tempRealm =>
        {

            try
            {
                foreach (IMaster data in dataList)
                {
                    IMaster dbData = null;

                    if (data.status.Equals(CREATED))
                    {


                        dbData = tempRealm.Find<T>(data.mId);

                        dbData.Id = data.Id;
                        dbData.syncInfo.isSync = SyncStatus.SYNCED;
                    }
                    else if (data.status.Equals(UPDATED))
                    {

                        // dbData = tempRealm.All<T>().FirstOrDefault(c => c.Id == data.Id);
                        dbData = tempRealm.All<T>().Where(c => c.Id == data.Id).FirstOrDefault();

                        dbData.Id = data.Id;
                        dbData.syncInfo.isSync = SyncStatus.SYNCED;




                    }
                    else if (data.status.Equals(ERROR))
                    {
                        if (!String.IsNullOrEmpty(dbData.mId))
                        {
                            dbData = tempRealm.Find<T>(data.mId);
                        }
                        else
                        {
                            dbData = tempRealm.All<T>().Where(c => c.Id == data.Id).FirstOrDefault();


                        }
                        dbData.syncInfo.errorMessage = data.errorMessage;
                        dbData.syncInfo.isSync = SyncStatus.NOT_SYNCED;
                    }


                }
            }catch(Exception e)
            {


                Debug.WriteLine("Error hi " + e.Message);
            }


        });
  }

one of my models of Contact

public class Contact : RealmObject , IMaster
{

    public long contactId { set; get; } = 0;
    [PrimaryKey]
    public String mContactId { get; set; } = Guid.NewGuid().ToString();        

    public SyncInfo syncInfo { get; set; }

    public String contactStatus { get; set; }

     public long Id
    {
        get
        {
           return  contactId;
        }

        set
        {
            contactId = value;
        }
    }

    public string mId
    {
        get
        {
            return mContactId;
        }

        set
        {
            mContactId = value;
        }
    }

    public string status
    {
        get
        {
            return contactStatus;
        }

        set
        {
            contactStatus = value;
        }
    }
}

Interface defination of IMaster which will be implemented by all other models

public interface IMaster
{
    long Id { get; set; }
    String mId { get; set; }
    SyncInfo syncInfo { get; set; }
    String status { get; set; }
    String errorMessage { get; set; }


}

Problem is at line tempRealm.All<Contact>() in updateData function , i can not generalize the fetching of data here i.e. i can not use tempRealm.All<T>() or tempRealm.All<IMaster>() as IMaster is an interface and its not derived from RealmObject.

it is possible in android using T dbInsertable = realm.where((Class<T>)insertable.getClass()).findFirst();

but not sure how to do in C#

so can anyone suggest how to fix this

Find<T> is not working enter image description here


Solution

  • if I understand...

    try this (adding T constraint to RealmObject):

    private async void updateData<T>(Realm realm, IList<T> dataList) where T : RealmObject, IMaster, new()
    {
       await realm.WriteAsync(tempRealm =>
       {
           foreach (IMaster data in dataList)
           {
               IMaster dbData = null;
               if (data.getStatus().Equals("CREATED"))
               {
                   // Problem is here at tempRealm.All<Contact>() i am not able to generlize the fetching of objects
                   dbData = tempRealm.Find<T>(data.getmId());
    
                   //you need to put these properties in IMaster (id, syncInfo)
                   dbData.id = data.id;
                   dbData.syncInfo.isSync = SyncStatus.SYNCED;
               }
           }
    
       });
    }