EF Core Scaffolded data and Property Changed

80 views Asked by At

I have a WPF application (MVVM Toolkit) with a data model which was scaffolded using EFcore tools from a database. The resulting model for one specific class looks like this:

public partial class BomLine
{
    public int Id { get; set; }
    public int ProjectId { get; set; }
    public string? Manufacturer { get; set; }
    public string? ManufacturerPartNumber { get; set; }

    public string? InternalPartNumberSelected { get; set; }
}

A list of such items ObservableCollection<BomLine> are displayed in a ListView. This works as expected. There is an additional binding on the value of InternalPartNumberSelected which gives the respective line a distinct color.

Now, when the value of InternalPartNumberSelected changes, no PropertyChanged event is fired (of course, there is no [ObservableProperty] or other explicit RaisePropertyChanged command.

I could now change the Scaffolded data to

public partial class BomLine : ObservableObject
{
    public int Id { get; set; }
    public int ProjectId { get; set; }
    public string? Manufacturer { get; set; }
    public string? ManufacturerPartNumber { get; set; }

    [ObservableProperty] string? _internalPartNumberSelected;
}

This would make the color change visible because now a Property Change event is fired and the Binding re-evalued.

Yet, this seems like a bad solution because it requires tinkering with scaffolded data (which would be overwritten).

Is there a "correct" approach to that problem? I'm using .net core 8 / efcore 8, WPF, MVVM toolkit.

1

There are 1 answers

1
Sinus32 On BEST ANSWER

You can keep separation of EF from view models by using an approach explained at https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/observableobject#wrapping-a-non-observable-model. In your case it would be something like this:

public class BomLineViewModel : ObservableObject
{
    private readonly BomLine model;

    public BomLineViewModel(BomLine model)
    {
        this.model = model;
    }

    public int Id
    {
        get => model.Id;
        // no setter, Id is readonly
    }

    public int ProjectId
    {
        get => model.ProjectId;
        set => SetProperty(model.ProjectId, value, model, (m, v) => m.ProjectId = v);
    }

    public string? Manufacturer
    {
        get => model.Manufacturer;
        set => SetProperty(model.Manufacturer, value, model, (m, v) => m.Manufacturer = v);
    }

    public string? ManufacturerPartNumber
    {
        get => model.ManufacturerPartNumber;
        set => SetProperty(model.ManufacturerPartNumber, value, model, (m, v) => m.ManufacturerPartNumber = v);
    }

    public string? InternalPartNumberSelected
    {
        get => model.InternalPartNumberSelected;
        set => SetProperty(model.InternalPartNumberSelected, value, model, (m, v) => m.InternalPartNumberSelected = v);
    }
}

That way you can add even other things to the view model and they won't affect EF.