Custom Adaptor for Supabase

I am trying to build a custom adaptor for Supabase (https://github.com/supabase-community/supabase-csharp)

Everything seems to be working except Grouping, I am getting the error in the comment in ReadAsync, without the grouping section I get rows returned but an empty grid.

Here is the code example I am working from
https://blazor.syncfusion.com/documentation/datagrid/custom-binding

'

using Syncfusion.Blazor.Data;

using Syncfusion.Blazor;

using System.Diagnostics;

using Microsoft.ApplicationInsights;

using RRMobile.Providers;

using System.Linq.Dynamic.Core;

using System.Security.Cryptography.Xml;

using System.Collections;


namespace RRMobilePortal.Adaptors

{

    public class SupabaseDataAdaptor<TModel> : DataAdaptor where TModel : AppBaseModel, new()

    {

        private readonly Lazy<Task<Supabase.Client>> _lazyClient;

        private readonly TelemetryClient _telemetryClient;

        private readonly IConfiguration _configuration;


        public SupabaseDataAdaptor(SupabaseClientFactory supabaseClientFactory, TelemetryClient telemetryClient, IConfiguration configuration)

        {

            _configuration = configuration;

            _telemetryClient = telemetryClient;

            _lazyClient = new Lazy<Task<Supabase.Client>>(async () =>

            {

                var client = await supabaseClientFactory.CreateClientAsync();

                return client;

            });

        }


        private async Task<Supabase.Client> GetClientAsync()

        {

            return await _lazyClient.Value;

        }


        public async override Task<object> ReadAsync(DataManagerRequest dm, string key = null)

        {

            try

            {

                var client = await GetClientAsync();

                var response = await client.From<TModel>().Get();

                var data = response.Models.AsQueryable();


                if (dm.Sorted != null && dm.Sorted.Any())

                {

                    var orderByExpressions = dm.Sorted.Select(s =>

                        s.Direction == "ascending"

                            ? s.Name

                            : s.Name + " descending"

                    );


                    string orderByClause = string.Join(", ", orderByExpressions);

                    data = data.OrderBy(orderByClause);

                }

                var totalCount = data.Count();


                if (dm.Skip != 0)

                {

                    data = data.Skip(dm.Skip);

                }


                if (dm.Take != 0)

                {

                    data = data.Take(dm.Take);

                }

                if (dm.Group != null)

                {

                    IEnumerable groupedData = Enumerable.Empty<object>();

                    foreach (var group in dm.Group)

                    {

                        groupedData = DataUtil.Group<TModel>(data, group, dm.Aggregates, 0, dm.GroupByFormatter).Cast<TModel>();

                        //Error: System.InvalidCastException: Unable to cast object of type 'Syncfusion.Blazor.Data.Group`1[RRMobilePortal.DataClasses.TrackTableData]' to type 'RRMobilePortal.DataClasses.TrackTableData'

                    }

                    return dm.RequiresCounts ? new DataResult() { Result = groupedData, Count = totalCount } : (object)groupedData;

                }

                var result = data.ToList();

                return dm.RequiresCounts ? new DataResult() { Result = result, Count = totalCount } : (object)result;

            }

            catch (Exception ex)

            {

                _telemetryClient.TrackException(ex);

                Console.WriteLine(ex.Message);

                if (Debugger.IsAttached) Debugger.Break();

                return null;

            }

        }

        public async override Task<object> InsertAsync(DataManager dataManager, object value, string key)

        {

            try

            {

                var client = await GetClientAsync();

                var model = value as TModel;

                var response = await client.From<TModel>().Insert(model);

                return response.Models.FirstOrDefault();

            }

            catch (Exception ex)

            {

                _telemetryClient.TrackException(ex);

                Console.WriteLine(ex.Message);

                if (Debugger.IsAttached) Debugger.Break();

                return null;

            }

        }


        public async override Task<object> UpdateAsync(DataManager dataManager, object value, string keyField, string key)

        {

            try

            {

                var client = await GetClientAsync();

                var data = value as TModel;

                var response = await client.From<TModel>().Upsert(data);

                return response.Models.FirstOrDefault();

            }

            catch (Exception ex)

            {

                _telemetryClient.TrackException(ex);

                Console.WriteLine(ex.Message);

                if (Debugger.IsAttached) Debugger.Break();

                return null;

            }

        }


        public async override Task<object> RemoveAsync(DataManager dataManager, object value, string keyField, string key)

        {

            try

            {

                var client = await GetClientAsync();

                var propertyInfo = typeof(TModel).GetProperty(keyField);

                Guid.TryParse(value.ToString(), out Guid Uid);

                if (propertyInfo == null)

                {

                    throw new ArgumentException($"Property '{keyField}' not found on type '{typeof(TModel).Name}'");

                }


                //var keyValue = propertyInfo.GetValue(value);

                await client.From<TModel>().Where(x => x.Id == Uid).Delete();

                return value;

            }

            catch (Exception ex)

            {

                _telemetryClient.TrackException(ex);

                Console.WriteLine(ex.Message);

                if (Debugger.IsAttached) Debugger.Break();

                return null;

            }

        }

    }

}
'


3 Replies

SK Sanjay Kumar Suresh Syncfusion Team December 17, 2024 05:14 AM UTC

Hi Mike,


We have validated your query and observed that the InvalidCastException occurs due to a redundant cast in the provided code snippet. We recommend removing the redundant cast to resolve the issue. Please refer the below code snippet for reference.



Code Snippet:

if (dm.Group != null)

{

    IEnumerable groupedData = Enumerable.Empty<object>();

    foreach (var group in dm.Group)

    {

        groupedData = DataUtil.Group<Order>(DataSource, group, dm.Aggregates, 0, dm.GroupByFormatter).Cast<Order>();

        //Error: System.InvalidCastException: Unable to cast object of type 'Syncfusion.Blazor.Data.Group`1[RRMobilePortal.DataClasses.TrackTableData]' to type 'RRMobilePortal.DataClasses.TrackTableData'

    }

 

    return dm.RequiresCounts ? new DataResult() { Result = groupedData, Count = DataSource.Count() } : (object)groupedData;

 

}



Regards,
Sanjay Kumar Suresh



MR Mike Rowley December 19, 2024 05:32 PM UTC

Excellent, thank you! 



NP Naveen Palanivel Syncfusion Team December 20, 2024 10:20 AM UTC

Hi Mike,


Welcome.

Kindly get back to us if you have further queries. As always we will be assist you.


Regards,
Naveen


Loader.
Up arrow icon