After a few years of experiencewith the EntityFramework, the time has come tostart studyingMVVM usingMVVM Light. I developeda small application thatwill perform the classicCRUD operations,and throughEF 6I created the"Model".
<Window x:Class="MvvmLightEf.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ignore="http://www.ignore.com" mc:Ignorable="d ignore" Height="480" Width="640" Title="MVVM Light Application" DataContext="{Binding Main, Source={StaticResource Locator}}" WindowStartupLocation="CenterScreen"><Window.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="Skins/MainSkin.xaml" /></ResourceDictionary.MergedDictionaries></ResourceDictionary></Window.Resources><Grid x:Name="LayoutRoot"><Grid.RowDefinitions><RowDefinition Height="34*"/><RowDefinition Height="415*"/></Grid.RowDefinitions><TextBlock FontSize="36" FontWeight="Bold" Foreground="Purple" Text="{Binding WelcomeTitle}" VerticalAlignment="Center" HorizontalAlignment="Center" TextWrapping="Wrap" Margin="316,160,316,207" Grid.Row="1" Height="48" Width="0" /><StackPanel Orientation="Horizontal" Grid.Row="0"><Button Content="New" Height="23" Name="btnNew" Width="75" Command="{Binding NewCommand}" /><Button Content="Search" Height="23" Name="btnSearch" Width="75" Command="{Binding SearchCommand}" /><Button Content="Delete" Height="23" Name="btnDelete" Width="75" Command="{Binding DeleteCommand}" /><Button Content="Save" Height="23" Name="btnSave" Width="75" Command="{Binding SaveCommand}" /><Button Content="Exit" Height="23" Name="btnExit" Width="75" Command="{Binding ExitCommand}" /></StackPanel><TextBox HorizontalAlignment="Left" Height="24" Margin="181,102,0,0" Grid.Row="1" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="50"/><TextBox HorizontalAlignment="Left" Height="24" Margin="181,131,0,0" Grid.Row="1" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="150"/><TextBox HorizontalAlignment="Left" Height="24" Margin="181,160,0,0" Grid.Row="1" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="150"/><Label Content="ID" HorizontalAlignment="Left" Margin="116,102,0,0" Grid.Row="1" VerticalAlignment="Top" Height="24" Width="51"/><Label Content="Name" HorizontalAlignment="Left" Margin="116,131,0,0" Grid.Row="1" VerticalAlignment="Top" Height="24" Width="51"/><Label Content="Surname" HorizontalAlignment="Left" Margin="116,160,0,0" Grid.Row="1" VerticalAlignment="Top" Height="24" Width="60"/></Grid></Window>
Customer.cs:
namespace MvvmLightEf.Model { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity.Spatial; [Table("Customer")] public partial class Customer { public int ID { get; set; } [StringLength(50)] public string Name { get; set; } [StringLength(50)] public string Surname { get; set; } } }
MyContext.cs:
public partial class MyContext : DbContext { public MyContext() : base("name=MyContext") { } public virtual DbSet<Customer> Customers { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { } }
ViewModelLocator.cs:
public class ViewModelLocator { private static MainViewModel _main; /// <summary> /// Initializes a new instance of the ViewModelLocator class. /// </summary> public ViewModelLocator() { ////if (ViewModelBase.IsInDesignModeStatic) ////{ //// // Create design time view models ////} ////else ////{ //// // Create run time view models ////} CreateMain(); } /// <summary> /// Gets the Main property. /// </summary> public static MainViewModel MainStatic { get { if (_main == null) { CreateMain(); } return _main; } } /// <summary> /// Gets the Main property. /// </summary> [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance","CA1822:MarkMembersAsStatic", Justification = "This non-static member is needed for data binding purposes.")] public MainViewModel Main { get { return MainStatic; } } /// <summary> /// Provides a deterministic way to delete the Main property. /// </summary> public static void ClearMain() { _main.Cleanup(); _main = null; } /// <summary> /// Provides a deterministic way to create the Main property. /// </summary> public static void CreateMain() { if (_main == null) { _main = new MainViewModel(); } } /// <summary> /// Cleans up all the resources. /// </summary> public static void Cleanup() { ClearMain(); } }
MainViewModel.cs:
public class MainViewModel : ViewModelBase { private readonly MyContext ctx; private RelayCommand saveCommand; private RelayCommand exitCommand; public ICommand SaveCommand { get { if (saveCommand == null) saveCommand = new RelayCommand(() => Save()); return saveCommand; } } public ICommand ExitCommand { get { if (exitCommand == null) exitCommand = new RelayCommand(() => Exit()); return exitCommand; } } private void Save() { throw new System.NotImplementedException(); } private void Exit() { Application.Current.Shutdown(); } /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel() { if (IsInDesignMode) { // Code runs in Blend --> create design time data. } else { // Code runs "for real" ctx = new MyContext(); } } public override void Cleanup() { // Clean up if needed base.Cleanup(); } }
Now thequestions: withEF, I have alwaysused a GenericRepository together withUoW.
namespace DAL { public class GenericRepository<T> : IGenericRepository<T> where T : class, new() { private MyContext ctx; private readonly DbSet<T> dbSet; public GenericRepository(MyContext context) { ctx = context; dbSet = ctx.Set<T>(); ctx.Configuration.LazyLoadingEnabled = false; ctx.Configuration.ProxyCreationEnabled = false; } public T Find(int id) { return dbSet.Find(id); } public void Insert(T entity) { dbSet.Add(entity); }
InMVVMthe RepositoryandtheUoWwhereI placethem?
To save Iwrote:
private IUnitOfWork uow; private Customer entity; private void RDB_Save() { using (uow = new UnitOfWork()) { entity = new Town() { Name= nameTextBox.Text, Surname = surnameTextBox.Text, }; uow.Customer.Insert(entity); uow.Save(); } }
Butnow,how can Ichangethe code inside theMainviewmodelto getthe same result?
SorryifI aska lot, butIforcedmyself tolearnMVVMtrying toforgetwhatI wrotewithWinForms.