Hello,
I'm trying out the Syncfusion components (v18.1.0.59) in a server-side Blazor project, using Visual Studio 2019 Enterprise (v16.6.3). The data is coming from a MariaDB instance hosted on a Raspberry Pi 4. I'm bringing that in using EF Core and the relevant package dependency (MySql.Data.EntityFrameworkCore v8.0.20). No problem retrieving the data.
I tried to follow the guidance at https://www.syncfusion.com/blogs/post/creating-a-master-detail-view-is-easier-with-blazor-datagrid.aspx for making a component that allows the user to drill into a particular stock (aka instrument) to see the price history for that stock. In the database, foreign keys are set up, one joining the Instruments table to the Prices table on the InstrumentID.
There were errors at first referring to a self-referencing loop. I got round that by adorning the relationship property in the Instruments class with: [JsonIgnore] and [IgnoreDataMember]. If I keep to this approach, it will be necessary to remember to edit the class file each time the model is refreshed from the database. I believe the problem comes from Syncfusion using Newtonsoft's JsonSerializer which, by default, processes each object by value instead of by reference. Anyway, it would be great if Syncfusion were able to address this so that auto-generated class files don't need to be hand-edited.
Moving on, I made the Detail template per the Master-Detail page guidelines and have since been faced with a null reference exception. That error refers to the grid columns in the Detail template but I can't see why. I've tried a few approaches and experiments, trying to narrow things down. One of which, so as to match the tutorial, was to comment out the relationship properties in the Instruments and Prices classes and to retrieve the data each in a separate call - this to better mimic the tutorial. Same null reference error. While the page renders fine, showing a grid of instruments, the error comes when I click the down-arrow to see the detail.
I don't seem to be able to paste images inline - please believe me when I say that both the instruments and prices lists are being returned bulging with data. For the simplest troubleshooting, I've set the Query attribute to look for a hard-coded value (an InstrumentID that is definitely in the database). When debugging, I can see that @prices is populated and that the context-based instrument has the expected ID. The field names use the same camel-cased spelling as in the underlying classes.
@page "/datamaintenance"
@using Data
@using Microsoft.EntityFrameworkCore
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.Grids
@inject DbContextOptions<FinancesContext> DbContext
@inject FinancesService service
@inject NavigationManager navManager
<h3>Data Maintenance</h3>
<SfGrid DataSource="@instruments">
<GridTemplates>
<DetailTemplate>
@{
var instrument = (context as Instruments);
Console.WriteLine(instrument.InstrumentId);
Console.WriteLine("Wait here to inspect");
<SfGrid DataSource="@prices" TValue="Prices" Query="@(new Query().Where("InstrumentId", "equal", 6))" AllowPaging="true">
<GridPageSettings PageSize="10"></GridPageSettings>
<GridColumn Field=@nameof(Prices.PriceDate) HeaderText="Price Date"></GridColumn>
<GridColumn Field=@nameof(Prices.CurrentPriceUsd) HeaderText="Current Price ($)" Format="N"></GridColumn>
</SfGrid>
}
</DetailTemplate>
</GridTemplates>
<GridColumns>
<GridColumn Field="InstrumentId" Visible="false"></GridColumn>
<GridColumn Field="InstrumentName" HeaderText="Instrument"></GridColumn>
</GridColumns>
</SfGrid>
@code {
private List<Instruments> instruments;
private List<Prices> prices;
protected override async Task OnInitializedAsync()
{
try
{
instruments = await service.GetInstrumentsAsync();
prices = await service.GetPricesAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private void RowSelectHandler(RowSelectEventArgs<Instruments> args)
{
Console.WriteLine(args.Data.InstrumentId);
}
}
As a side point, it would be nice to know why some of the documentation uses syntax along the lines of Field="InstrumentId" , other parts use @nameof(Instruments.InstrumentId). Is there a difference behind the scenes?
Any assistance getting past this will be much appreciated. Many thanks.