Using Reflection when parsing a Csv file to generically write entity property values to a Members table in an Azure SQL database using Entity Framework Core.

<EditForm OnValidSubmit=@HandleSubmit Model="@msg">

    <div class="form-group">
        <TelerikTextArea @bind-Value="@msg.Names"
                         Id="msgId"
                         Name="Message"
                         Label="Enter Column Names"
                         AutoSize="false">
        </TelerikTextArea>
    </div>

    <div class="form-group" style="width: 500px;">
        <TelerikTextArea @bind-Value="@msg.Values"
                         Id="louTextArea"
                         Name="ListOfUsersTextArea"
                         Label="Enter Values"
                         AutoSize="false">
        </TelerikTextArea>
    </div>

    <input type="submit" class="btn btn-primary" value="Send" />
</EditForm>

The Razor UI for submitting the Csv text

Nb: There is an ongoing issue with Telerik TextAreas in not being able to directly set the Width property. But you only do a clipboard paste so it doesn’t matter here.

  nv.Names = msg.Names.Trim();
  nv.Values = msg.Values.Trim();
  // Some cursory checks here (not shown)
  string[] csvLines = new string[] { nv.Names, nv.Values };
  UpdateResults(await service.AddMemberviaCSV(csvLines));

The client-side code for submitting one member


Apart from the CSV functionality, when directly editing an existing member in the Edit Member dialog, updating a member by submitting the updated instance when submitted from a Telerik Grid entity update was found to be problematic:

An error occurred while saving changes. Error details: The instance of entity type Member cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. …

This was resolved by using Reflection to iterate through the class properties and to copy the values from the submitted instance to that under the watch of the DbContext Tracking. Whilst again there are probably better ways of doing this, this code was quite useful for the CSV parsing:

  • Form an array of field names from the header.
  • For each property in Member class:
    • Get the index of the field name from the header array
    • If it doesn’t exist skip this property
    • Also skip if not writeable
    • Get the corresponding string value from the values line
    • Parse it as an int, DataTime, then Double, aborting that sequence with a successful parse.
      • Otherwise use the string value
        • If #COMMA# is in the string, replace it now with a comma.
    • Check that the property type is the int, DateTime, Double or string type as determined above.
      • If so, set the property to the successfully parsed value.
      • Skip this property otherwise.
  • For the AddNewMember method, if the member with the First and Last Names as well as the DOB is in the Members, call the Update method.
  • In the UpdateMember just check that those 3 properties have been provided
    • Not really necessary but good to recheck.

The code for this algorithm is shown in the next post.

The AddNewMembers and UpdateMember methods are about 80% the same code and could be merged into one. But for simplicity and clarity the second was created as a separate method by copying the first and modifying to be just and update.

Note that the use of this algorithm facilitates the submission of only partial data. So if updating, you only need to sub,it the three required properties and well as the properties to be updated.


 TopicSubtopic
   
 This Category Links 
Category:Blazor Index:Blazor
  Next: > Blazor Helpers App Members
<  Prev:   Blazor Helpers App Members