radzenhq / radzen-blazor

Radzen Blazor is a set of 90+ free native Blazor UI components packed with DataGrid, Scheduler, Charts and robust theming including Material design and FluentUI.
https://www.radzen.com
MIT License
3.55k stars 790 forks source link

UpdateRow of DataGrid inline edit causes KeyNotFoundException #905

Open Wolfware2023 opened 1 year ago

Wolfware2023 commented 1 year ago

I am replicating the example DataGrid inline edit Displaying and switching to edit mode works fine. But when I change a text value and save it, I get an error during the call of await objectGrid.UpdateRow(currentObject);

The error message is

Error: System.Collections.Generic.KeyNotFoundException: The given key 'MyObject { RowGuid = bb19826e-70fd-5a5c-9eeb-0567cd3ac95d, TextProperty = NewText,  CreatedAt = 06.04.2023 13:13:40, CreatedById = ab460de4-5431-479f-b064-d303a58a2023, EditedAt = , EditedById =  }' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Radzen.Blazor.RadzenDataGrid`1.UpdateRow(TItem item)
   at Pages.ExamplePage.SaveRow(MyObject currentObject) in 

To Reproduce Steps to reproduce the behavior:

  1. Copy the code from the example
  2. Remove all code with db context
  3. Replace order with your own object. Mine only had 4 string properties.
  4. See error

Expected behavior It should work without error like in the example, calling the method defined for RowUpdate next.

Additional context

enchev commented 1 year ago

Hey @Wolfware2023,

Please post runnable code replicating the exception.

Wolfware2023 commented 1 year ago

While removing more company code, I noticed my mistake. MyObject was not a class, but of type record. That caused the exception. Now with it being a class, it works as expected. Thanks.

XorZy commented 1 year ago

I have encountered the same issue. This happens with records or any type that override Equals. The exception happens because of this line: https://github.com/radzenhq/radzen-blazor/blob/cae80096e12802de1498857272f0bce5f3b3bd77/Radzen.Blazor/RadzenDataGrid.razor.cs#L2380C28-L2380C28 If you use a record (which compares by value), or implement a custom comparison logic, it is more than likely the comparison will fail since you are, after all, editing the columns. This does not happen on vanilla classes since the default comparator only compares references, not actual values. Imho this is a bug since I don't think this should happen, especially if you specify a custom KeyProperty.

ghhv commented 1 year ago

Arghh.. just got bitten by this again since I'm using records for my ViewModels.. which I thought was good practice.. and doesn't seem like there's any other way to resolve this... :-(

enchev commented 1 year ago

Records are immutable types, changing the data requires creating of new objects.

XorZy commented 1 year ago

C# records are not necessarily immutable. One could very well want to use the automatic equality comparison of records without requiring it to be immutable, and this is in fact a supported use case. And in any case, as I noted, regular classes which override Equals will also trigger this exception. In my opinion it does not make sense to rely on the instance-provided equality comparison in an 'edit' context since the object is most likely going to be mutated. If it compares by anything other than reference, you are going to get bitten by this.

The editContext dictionary should override the provided equality comparison and use a reference comparer instead. If that is not feasible, one should be able to provide a custom equality comparer to override the default, or at the very least specify which property should be used for equality comparison.

bdongus commented 6 months ago

I ran into this issue too. Supporting mutable records would be really nice.

Wolfware2023 commented 1 month ago

Ok sure. I'll reopen this issue then.

enchev commented 1 month ago

Hey @Wolfware2023, We accept pull requests also!