How can I create dynamic properties of database columns at runtime?

Hi there! I want to create syncfussion datagrid fully dynamically. I'm trying to create a dynamic class that creates properties at runtime instead of hard-coded properties. Please guide me on how can i do that.

What I tried:

//Sp Class

 public class Sp : DynamicObject

    {

        Dictionary<string, object> properties = new Dictionary<string, object>();

        public override bool TryGetMember(GetMemberBinder binder, out object result)

        {

            string name = binder.Name;

            return properties.TryGetValue(name, out result);

        }

        public override bool TrySetMember(SetMemberBinder binder, object value)

        {

            properties[binder.Name] = value;

            return true;

        }

        public override IEnumerable<string> GetDynamicMemberNames()

        {

            return properties?.Keys;

        }

    }


//ApplicationDbContext

public class ApplicationDbContext:DbContext

    {

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options)

        {


        }

        public DbSet<Sp> DisplaySp { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)

        {

            modelBuilder.Entity<Sp>().HasNoKey();

            base.OnModelCreating(modelBuilder);

        }

    }


//Controller Side

[HttpGet]

        [Route("Getspdetails")]

        public Task<List<Sp>> GetData()

        {

            var result = _services.Get();

            return result;

        }


//Service 

public async Task<List<Sp>> Get()

        {

            var data = _context.DisplaySp.FromSqlRaw("Execute Tbl_DailySaleRpSP @nType = 0,@nsType = 2").ToList();

            return data;

        }


//Razor Page

<SfGrid DataSource="@Spdetails" AllowPaging="true" AllowFiltering="true" AllowSorting="true">

        <GridPageSettings PageSize="10"></GridPageSettings>

        <GridAggregates>

            <GridAggregate>

                <GridAggregateColumns>

                    @foreach (var col in columns)

                    {

                        <GridAggregateColumn Field="@col" Type="AggregateType.Sum">

                            <FooterTemplate>

                                @{

                                    var aggregate = (context as AggregateTemplateContext);

                                    <div>

                                        <p>@aggregate?.Sum</p>

                                    </div>

                                }

                            </FooterTemplate>

                        </GridAggregateColumn>

                    }

                </GridAggregateColumns>

            </GridAggregate>

        </GridAggregates>

    </SfGrid>

@code {

    public List<Sp> Spdetails { get; set; } = new List<Sp>();

    public List<string> columns { get; set; } = new List<string>();

    protected override async Task OnInitializedAsync()

    {

        Spdetails = await Http.GetFromJsonAsync<List<Sp>>("Getspdetails");

        if (Spdetails != null && Spdetails.Count > 0) {

            PropertyInfo[] props = typeof(Sp).GetProperties();

            foreach (var prop in props)

            {

                if (prop.PropertyType == typeof(int) || prop.PropertyType == typeof(double) || prop.PropertyType == typeof(decimal))

                {

                    columns.Add(prop.Name);

                }

            }

        }

    }

}


Please look through the code and guide me as right now I'm getting error of "Sequence got no elements".


3 Replies

NP Naveen Palanivel Syncfusion Team November 14, 2023 01:55 AM UTC

Hi Muhammad,

Based on your query, we suspect that the columns in your dataset are defined at runtime. Our grid component is designed to work with strongly typed data binding, which requires a specific model type (class) for binding. However, we have alternative options for your scenario. We recommend using either ExpandoObjectBinding or DynamicObjectBinding. These options allow you to bind data dynamically when the model type is unknown. For detailed information on how to use these binding options, please consult the documentation provided below:



Reference : https://blazor.syncfusion.com/documentation/datagrid/data-binding#expandoobject-binding

                    https://blazor.syncfusion.com/documentation/datagrid/data-binding#dynamicobject-binding                     

If we misunderstood your query kindly get back to us.

Regards,

Naveen Palanivel



MU Muhammad Usman replied to Naveen Palanivel November 19, 2023 04:53 PM UTC

Hello!

I tried using DynamicObjectBinding and I got "Sequence contains no elements". Please check my code and help me.

Here's my code:

Service side code:

public async Task<IEnumerable<Sp>> Get()

        {

            var data = await _context.DisplaySp.FromSqlRaw("Execute Tbl_DailySaleRpSP @nType = 0,@nsType = 2").ToArrayAsync();

            return data;

        }


Controller side code:

        [HttpGet]

        [Route("Getspdetails")]

        public Task<IEnumerable<Sp>> GetData()

        {

            return _services.Get();

        }


Razor page code:

@code {

    public List<Sp> Spdetails { get; set; } = new List<Sp>() {};


    public List<string> columns { get; set; } = new List<string>() {};


    protected override async Task OnInitializedAsync()

    {

        Spdetails = await Http.GetFromJsonAsync<List<Sp>>("Getspdetails");


        if (Spdetails != null && Spdetails.Any())

        {

            var firstItem = Spdetails[0] as IDictionary<string, object>;

            columns = firstItem.Keys.Where(key =>

            {

                var value = firstItem[key];

                return value is int || value is double || value is decimal;

            }).ToList();

        }

    }

}



PS Prathap Senthil Syncfusion Team November 20, 2023 04:02 PM UTC

Before proceeding with the reporting problem, we require some additional clarification from your end. Please share the below details to proceed further at our end.


  1. Share with us the NuGet version you have used.
  2. Please provide us with a simple, reproducible sample of the issue with duplicate data.
  3. If possible, a video demonstration of the problem would be greatly appreciated as it can help us identify the issue more effectively.

Above-requested details will be very helpful in validating the reported query at our end and providing a solution as early as possible.



Loader.
Up arrow icon