Search code examples
.net-corereactiveuiavaloniaui

View Model with EntityFrameworkCore


I started teaching myself .net-core and Avalonia UI.

I started the Avalonia UI Tutorial and it worked as expected. http://www.avaloniaui.net/docs/tutorial/creating-model-viewmodel

But as it is most time, you can copy the code from the tutorial and it works, but you didn't understand it ...

Now I thought, ok change the "fake database" to a real database. So I started including Microsoft.EmtityFrameworkCore. The database exist, is included and it compiles and runs.

namespace Decksumme.Models
{
    public class ParticipantsContext : DbContext
    {
        public DbSet<Participant> Participants { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=decksumme.db");
        }
    }
}

I updated the ListViewModel

namespace Decksumme.ViewModels
{
    public class DecksummeListViewModel : ViewModelBase
    {
        public DecksummeListViewModel(DbSet<Participant> participants)
        {
            Participants = new ObservableCollection<DbSet<Participant>>();
        }

        public ObservableCollection<DbSet<Participant>> Participants { get; }
    }
}

The edit view model was anhanced to and compiles without error

namespace Decksumme.ViewModels
{
    class EditParticipantViewModel : ViewModelBase
    {
        string forename;
        string name;
        string discipline;

        public EditParticipantViewModel()
        {
            var okEnabled = this.WhenAnyValue(
                x => x.forename,
                x => !string.IsNullOrWhiteSpace(x)
            );

            Ok = ReactiveCommand.Create(
                () => new Participant
                {
                    Forename = Forename,
                    Name = Name,
                    Discipline = Discipline,
                },
                okEnabled
            );
            Cancel = ReactiveCommand.Create(() => { });
        }
        public string Forename { 
            get => forename; 
            set =>  this.RaiseAndSetIfChanged(ref forename, value); 
        }
        public string Name { 
            get => name; 
            set => this.RaiseAndSetIfChanged(ref name, value);
        }
        public string Discipline { 
            get => discipline; 
            set => this.RaiseAndSetIfChanged(ref discipline, value);
        }
        public string Results { get; set; }

        public ReactiveCommand<Unit, Participant> Ok { get; }
        public ReactiveCommand<Unit, Unit> Cancel { get; }
    }
}

Now the point I'm lost right now, the MainWondowViewModel.

namespace Decksumme.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        ViewModelBase content;

        public MainWindowViewModel(ParticipantsContext db)
        {
            Content = List = new DecksummeListViewModel(db.Participants);
        }

        public ViewModelBase Content
        {
            get => content;
            private set => this.RaiseAndSetIfChanged(ref content, value);
        }

        public DecksummeListViewModel List { get; }

        public void AddParticipant()
        {
            var vm = new EditParticipantViewModel();

            Observable.Merge(
                vm.Ok,
                vm.Cancel.Select(_ => (Participant)null))
                .Take(1)
                .Subscribe(model =>
                {
                    if(model != null)
                    {
                        List.Participants.Add(model);
                    }

                    Content = List;
                });

            Content = vm;
        }
    }
}

At the AddParticipant method. List.Participant.add(model); gets me the error

ViewModels\MainWindowViewModel.cs(39,47): error CS1503: Argument "1": Konvertierung von "Decksumme.Models.Participant" in "Microsoft.EntityFrameworkCore.DbSet<Decksumme.Models.Participant>" nicht möglich.

Now the question where the lack of knowledge is. Did I understand the Observable wrong? Did I used the db wrong? Or do I have to make a conversion at some point?


Solution

  • OMG, @kekekeks was right. This is the solution for the build error.

    namespace Decksumme.ViewModels
    {
        public class DecksummeListViewModel : ViewModelBase
        {
            public DecksummeListViewModel(DbSet<Participant> participants)
            {
                Participants = new ObservableCollection<Participant>(participants);
            }
    
            public ObservableCollection<Participant> Participants { get; }
        }
    }
    

    Need to be tested.