Using Record Results in QueryableExtensions.Select Error on Filter/Sort

Consider the following DTO:

public sealed class LicenseSummaryView

{

    [Key]

    public ulong Identity { get; init; }

    public DateTimeOffset Created { get; init; }

    public Guid Issuance { get; init; }

    public required string Name { get; init; }

    public Guid Author { get; init; }

    public bool Mature { get; init; }

    public required string AuthorName { get; init; }

    public uint? Owner { get; init; }

    public string? OwnerName { get; init; }

    public uint Index { get; init; }

    public uint Total { get; init; }

    public LicenseState State { get; init; }

}

Now switch it to this:

public sealed record LicenseSummaryView(
	[property: Key] ulong Identity,
	DateTimeOffset Created,
	Guid Issuance,
	string Name,
	Guid Author,
	bool Mature,
	string AuthorName,
	uint? Owner,
	string? OwnerName,
	uint Index,
	uint Total,
	LicenseState State)
;


When attempting to sort/filter on the State property on an SfGrid, an error is thrown:

System.ArgumentException: Type 'Starbeam.Entities.Marketplace.Publishing.LicenseSummaryView' does not have a default constructor (Parameter 'type')

   at NewExpression System.Linq.Expressions.Expression.New(Type type)

   at IQueryable Syncfusion.Blazor.Data.QueryableExtensions.Select<T>(IQueryable source, string propertyName, Type sourceType) x 2

   at IQueryable<T> DragonSpark.SyncfusionRendering.Queries.PerformSelect<T>.Get(PerformSelectInput<T> parameter) in .../Framework/DragonSpark.Syncfusion/Queries/PerformSelect.cs:line 30

For reference, the following line is being called into your API:

https://github.com/DragonSpark/Framework/blob/4f18a559a39415e47df21d2c14f0d92ea53901f5/DragonSpark.Syncfusion/Queries/PerformSelect.cs#L30

It would be ideal if  QueryableExtensions.Select supported records.

Thank you for any consideration.


3 Replies

PS Prathap Senthil Syncfusion Team July 22, 2026 12:20 PM UTC

Hi Mike,

We have analyzed the behavior and found that the issue occurs because the QueryableExtensions.Select method expects the model type to have a parameterless (default) constructor when creating the projection internally. In the class-based model, a default constructor is available implicitly, so filtering and sorting operations work as expected. However, when the model is converted to a positional record, the compiler generates only a parameterized constructor and no default constructor. As a result, QueryableExtensions.Select is unable to create an instance of the record type and throws the exception. To resolve this issue, you can add an explicit parameterless constructor to the record, for example:


public sealed record LicenseSummaryView(

    ulong Identity,

    DateTimeOffset Created,

    Guid Issuance,

    string Name,

    Guid Author,

    bool Mature,

    string AuthorName,

    uint? Owner,

    string? OwnerName,

    uint Index,

    uint Total,

    LicenseState State)

{

    public LicenseSummaryView()

        : this(default, default, default, string.Empty,

               default, default, string.Empty,

               default, default, default, default, default)

    {

    }

}

 


Alternatively, you can use a record with property declarations instead of a positional record or continue using a class-based model. If you are using the sealed record providing a parameterless constructor allows the Grid's filtering and sorting operations to function correctly because the internal projection logic can successfully instantiate the type. For your convenience, we have attached a code snippet and a sample for reference.


Code Snippet:

  public sealed record Order(

   [property: Key] int? OrderID,

   string? CustomerID,

   int? EmployeeID,

   string? ShipCountry,

   string? ShipAddress,

   string? ShipName,

   string? ShipCity)

  {

      public Order()

          : this(default, default, default, default, default, default, default)

      {

      }

  }

 


Sample: Check the attachment.


Note: Copy the database path and update the connection string in the appsettings.json file with the copied path, based on the NORTHWIND.MDF file located in the App_Data folder. Then you can run the sample.


Regards,
Prathap Senthil


Attachment: BlazorDataGrid_PerformSelect_e3575e8.zip


MI Mike-E July 24, 2026 06:20 AM UTC

Hi Prathap,

Thank you for your reply.  Other APIs such as System.Text.Json.Serializer work perfectly fine with records without any modifications to the target schema.  May I ask why your API requires a parameterless constructor while other modern APIs do not?

Thank you for your consideration,

Michael



PS Prathap Senthil Syncfusion Team August 5, 2026 08:06 AM UTC

Thanks for the update .

Currently, we don’t have support for positional record types in QueryableExtensions.Select without requiring a parameterless constructor. However, we have considered this as an improvement and logged a task titled "Support positional record types in QueryableExtensions.Select without requiring a parameterless constructor. At the planning stage for every release cycle, we review all open features and identify features for implementation based on specific parameters including product vision, technological feasibility, and customer interest. And this improvement will be included in any of our upcoming releases.


You can now track the current status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link.


https://www.syncfusion.com/feedback/75134/support-positional-record-types-in-queryableextensions-select-without-requiring-a


You can also communicate with us regarding this open feature request at any time through the feedback page mentioned above. Currently, we do not have an immediate plan to implement this feature. However, we review and prioritize improvements during every release cycle based on customer demand, product vision, and technical feasibility. Therefore, this enhancement will be considered for inclusion in one of our future releases.


Loader.
Up arrow icon