How to improve WPF login with Entity Framework? Sometimes getting NullReferenceException and blocking doesn't work

Lutter 0 Баллы репутации
2026-06-15T18:34:07.19+00:00
Hello,

I am working on a WPF application for a store (exam project). I have implemented authorization with roles (Admin, Manager, User) and a block after 3 failed attempts. But sometimes I get a NullReferenceException and the block doesn't always save to the database. Also I'm not sure about my architecture.

Below is my full code. Please tell me what I can improve.

Thank you!

Problem 1: NullReferenceException**
Sometimes when I enter a wrong password, I get a NullReferenceException. I think it happens when the user is not found in the database, but I'm not sure. I added null checking but the error still appears randomly.

<Code block 1: Models>
// ----------------------------  Models.cs ----------------------------
// using System;
// using System.Collections.Generic;
// using System.ComponentModel.DataAnnotations;
// using System.ComponentModel.DataAnnotations.Schema;
//
// namespace Store
// {
//     public class Product
//     {
//         public int Id { get; set; }
//         public string Name { get; set; }
//         public string Description { get; set; }
//         public decimal Price { get; set; }
//         public int Stock { get; set; }
//         public int Discount { get; set; }
//         public string ImagePath { get; set; }
//         public int CategoryId { get; set; }
//         public int ManufacturerId { get; set; }
//         public virtual Category Category { get; set; }
//         public virtual Manufacturer Manufacturer { get; set; }
//     }
//
//     public class Category
//     {
//         public int Id { get; set; }
//         public string Name { get; set; }
//         public virtual ICollection<Product> Products { get; set; }
//     }
//
//     public class Manufacturer
//     {
//         public int Id { get; set; }
//         public string Name { get; set; }
//         public virtual ICollection<Product> Products { get; set; }
//     }
//
//     public class Order
//     {
//         public int Id { get; set; }
//         public DateTime OrderDate { get; set; }
//         public DateTime? PickupDate { get; set; }
//         public string Status { get; set; }
//         public string PickupAddress { get; set; }
//         public int UserId { get; set; }
//         public virtual User User { get; set; }
//         public virtual ICollection<OrderItem> OrderItems { get; set; }
//     }
//
//     public class OrderItem
//     {
//         public int Id { get; set; }
//         public int OrderId { get; set; }
//         public int ProductId { get; set; }
//         public int Quantity { get; set; }
//         public virtual Order Order { get; set; }
//         public virtual Product Product { get; set; }
//     }
//
//     public class User
//     {
//         public int Id { get; set; }
//         public string Login { get; set; }
//         public string Password { get; set; }
//         public string FullName { get; set; }
//         public string Role { get; set; }
//         public bool IsBlocked { get; set; }
//     }
// }
<Code block 2: DbContext>
// ---------------------------- ФАЙЛ 2: StoreContext.cs ----------------------------
// using Microsoft.EntityFrameworkCore;
//
// namespace Store
// {
//     public class StoreContext : DbContext
//     {
//         public DbSet<Product> Products { get; set; }
//         public DbSet<Category> Categories { get; set; }
//         public DbSet<Manufacturer> Manufacturers { get; set; }
//         public DbSet<Order> Orders { get; set; }
//         public DbSet<OrderItem> OrderItems { get; set; }
//         public DbSet<User> Users { get; set; }
//
//         protected override void OnConfiguring(DbContextOptionsBuilder options)
//             => options.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=StoreDB;Trusted_Connection=True;");
//
//         protected override void OnModelCreating(ModelBuilder modelBuilder)
//         {
//             modelBuilder.Entity<OrderItem>()
//                 .HasKey(oi => new { oi.OrderId, oi.ProductId });
//
//             modelBuilder.Entity<Order>()
//                 .Property(o => o.Status)
//                 .HasDefaultValue("Новый");
//
//             modelBuilder.Entity<User>()
//                 .HasIndex(u => u.Login)
//                 .IsUnique();
//
//             modelBuilder.Entity<Category>().HasData(
//                 new Category { Id = 1, Name = "Кроссовки" },
//                 new Category { Id = 2, Name = "Ботинки" },
//                 new Category { Id = 3, Name = "Сандалии" }
//             );
//
//             modelBuilder.Entity<Manufacturer>().HasData(
//                 new Manufacturer { Id = 1, Name = "Nike" },
//                 new Manufacturer { Id = 2, Name = "Adidas" },
//                 new Manufacturer { Id = 3, Name = "Reebok" }
//             );
//
//             modelBuilder.Entity<User>().HasData(
//                 new User { Id = 1, Login = "admin", Password = "admin123", FullName = "Администратор", Role = "Администратор", IsBlocked = false },
//                 new User { Id = 2, Login = "manager", Password = "manager123", FullName = "Менеджер Иванов", Role = "Менеджер", IsBlocked = false },
//                 new User { Id = 3, Login = "user", Password = "user123", FullName = "Клиент Петров", Role = "Клиент", IsBlocked = false }
//             );
//         }
//     }
// }
<Code block 3: 
// ---------------------------- ФАЙЛ 3: MainWindow.xaml ----------------------------
// <Window x:Class="Store.MainWindow"
//         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//         Title="Магазин обуви" Height="650" Width="1000">
//
//     <Grid Margin="10">
//         <Grid.RowDefinitions>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="*"/>
//             <RowDefinition Height="Auto"/>
//         </Grid.RowDefinitions>
//
//         <TextBlock Text="Магазин обуви" FontSize="24" FontWeight="Bold" HorizontalAlignment="Center" Margin="5"/>
//
//         <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,10">
//             <TextBlock Text="Поиск:" VerticalAlignment="Center" Margin="5"/>
//             <TextBox x:Name="SearchBox" Width="200" Margin="5" TextChanged="SearchBox_TextChanged"/>
//
//             <TextBlock Text="Поставщик:" VerticalAlignment="Center" Margin="20,5,5,5"/>
//             <ComboBox x:Name="FilterCombo" Width="150" Margin="5" SelectionChanged="FilterCombo_SelectionChanged"/>
//
//             <TextBlock Text="Сортировка:" VerticalAlignment="Center" Margin="20,5,5,5"/>
//             <ComboBox x:Name="SortCombo" Width="180" Margin="5" SelectionChanged="SortCombo_SelectionChanged"/>
//         </StackPanel>
//
//         <DataGrid x:Name="ProductsGrid" Grid.Row="2" AutoGenerateColumns="False" IsReadOnly="True"
//                   SelectionMode="Single" Margin="0,10" AlternatingRowBackground="LightGray"
//                   RowStyle="{StaticResource ProductRowStyle}">
//             <DataGrid.Columns>
//                 <DataGridTextColumn Header="Название" Binding="{Binding Name}" Width="150"/>
//                 <DataGridTextColumn Header="Категория" Binding="{Binding Category.Name}" Width="100"/>
//                 <DataGridTextColumn Header="Производитель" Binding="{Binding Manufacturer.Name}" Width="100"/>
//                 <DataGridTextColumn Header="Цена" Binding="{Binding Price, StringFormat='{0:C}'}" Width="80"/>
//                 <DataGridTextColumn Header="Скидка" Binding="{Binding Discount}" Width="60"/>
//                 <DataGridTextColumn Header="Цена со скидкой" Binding="{Binding FinalPrice, StringFormat='{0:C}'}" Width="100"/>
//                 <DataGridTextColumn Header="В наличии" Binding="{Binding Stock}" Width="80"/>
//             </DataGrid.Columns>
//         </DataGrid>
//
//         <StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10">
//             <Button x:Name="LoginBtn" Content="Войти" Click="LoginBtn_Click" Width="80" Margin="5"/>
//             <Button x:Name="GuestBtn" Content="Гость" Click="GuestBtn_Click" Width="80" Margin="5"/>
//             <Button x:Name="OrdersBtn" Content="Заказы" Click="OrdersBtn_Click" Width="80" Margin="5" Visibility="Collapsed"/>
//             <Button x:Name="AddProductBtn" Content="Добавить товар" Click="AddProductBtn_Click" Width="120" Margin="5" Visibility="Collapsed"/>
//             <Button x:Name="EditProductBtn" Content="Редактировать" Click="EditProductBtn_Click" Width="100" Margin="5" Visibility="Collapsed"/>
//             <Button x:Name="DeleteProductBtn" Content="Удалить" Click="DeleteProductBtn_Click" Width="80" Margin="5" Visibility="Collapsed"/>
//             <Button x:Name="UnblockUserBtn" Content="Разблокировать пользователя" Click="UnblockUserBtn_Click" Width="180" Margin="5" Visibility="Collapsed"/>
//             <Button x:Name="LogoutBtn" Content="Выйти" Click="LogoutBtn_Click" Width="80" Margin="5" Visibility="Collapsed"/>
//         </StackPanel>
//     </Grid>
// </Window>
--------
// ---------------------------- MainWindow.xaml.cs ----------------------------
// using System.Linq;
// using System.Windows;
// using Microsoft.EntityFrameworkCore;
//
// namespace Store
// {
//     public partial class MainWindow : Window
//     {
//         private StoreContext db = new StoreContext();
//         private User currentUser = null;
//
//         public MainWindow()
//         {
//             InitializeComponent();
//             LoadFiltersAndSorts();
//             LoadProducts();
//         }
//
//         private void LoadFiltersAndSorts()
//         {
//             var suppliers = db.Products.Select(p => p.Manufacturer.Name).Distinct().ToList();
//             suppliers.Insert(0, "Все поставщики");
//             FilterCombo.ItemsSource = suppliers;
//             FilterCombo.SelectedIndex = 0;
//
//             SortCombo.ItemsSource = new[] { "По возрастанию количества", "По убыванию количества" };
//             SortCombo.SelectedIndex = 0;
//         }
//
//         private void LoadProducts()
//         {
//             var query = db.Products
//                 .Include(p => p.Category)
//                 .Include(p => p.Manufacturer)
//                 .AsQueryable();
//
//             string search = SearchBox.Text?.ToLower();
//             if (!string.IsNullOrEmpty(search))
//                 query = query.Where(p => p.Name.ToLower().Contains(search) || p.Description.ToLower().Contains(search));
//
//             if (FilterCombo.SelectedIndex > 0)
//                 query = query.Where(p => p.Manufacturer.Name == FilterCombo.SelectedItem.ToString());
//
//             if (SortCombo.SelectedIndex == 0)
//                 query = query.OrderBy(p => p.Stock);
//             else
//                 query = query.OrderByDescending(p => p.Stock);
//
//             var list = query.ToList().Select(p => new
//             {
//                 p.Id,
//                 p.Name,
//                 p.Category,
//                 p.Description,
//                 p.Manufacturer,
//                 p.Price,
//                 p.Discount,
//                 FinalPrice = p.Price * (1 - p.Discount / 100m),
//                 p.Stock,
//                 p.ImagePath
//             }).ToList();
//
//             ProductsGrid.ItemsSource = list;
//         }
//
//         private void SearchBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) => LoadProducts();
//         private void FilterCombo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) => LoadProducts();
//         private void SortCombo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) => LoadProducts();
//
//         private void LoginBtn_Click(object sender, RoutedEventArgs e)
//         {
//             var loginWin = new LoginWindow(db);
//             if (loginWin.ShowDialog() == true)
//             {
//                 currentUser = loginWin.AuthenticatedUser;
//                 UpdateUIForRole();
//             }
//         }
//
//         private void GuestBtn_Click(object sender, RoutedEventArgs e)
//         {
//             currentUser = null;
//             UpdateUIForRole();
//         }
//
//         private void UpdateUIForRole()
//         {
//             bool isAdmin = currentUser != null && currentUser.Role == "Администратор";
//             bool isManager = currentUser != null && (currentUser.Role == "Администратор" || currentUser.Role == "Менеджер");
//
//             OrdersBtn.Visibility = isManager ? Visibility.Visible : Visibility.Collapsed;
//             AddProductBtn.Visibility = isAdmin ? Visibility.Visible : Visibility.Collapsed;
//             EditProductBtn.Visibility = isAdmin ? Visibility.Visible : Visibility.Collapsed;
//             DeleteProductBtn.Visibility = isAdmin ? Visibility.Visible : Visibility.Collapsed;
//             UnblockUserBtn.Visibility = isAdmin ? Visibility.Visible : Visibility.Collapsed;
//             LogoutBtn.Visibility = currentUser != null ? Visibility.Visible : Visibility.Collapsed;
//             LoginBtn.Visibility = currentUser == null ? Visibility.Visible : Visibility.Collapsed;
//             GuestBtn.Visibility = currentUser == null ? Visibility.Visible : Visibility.Collapsed;
//
//             if (currentUser != null)
//                 MessageBox.Show($"Вы успешно авторизовались. Добро пожаловать, {currentUser.FullName}");
//
//             LoadProducts();
//         }
//
//         private void OrdersBtn_Click(object sender, RoutedEventArgs e)
//         {
//             new OrdersWindow(db).ShowDialog();
//         }
//
//         private void AddProductBtn_Click(object sender, RoutedEventArgs e)
//         {
//             var win = new ProductEditWindow(db);
//             if (win.ShowDialog() == true)
//                 LoadProducts();
//         }
//
//         private void EditProductBtn_Click(object sender, RoutedEventArgs e)
//         {
//             var selected = ProductsGrid.SelectedItem;
//             if (selected == null)
//             {
//                 MessageBox.Show("Выберите товар для редактирования");
//                 return;
//             }
//
//             int id = (int)selected.GetType().GetProperty("Id").GetValue(selected);
//             var product = db.Products.Find(id);
//             var win = new ProductEditWindow(db, product);
//             if (win.ShowDialog() == true)
//                 LoadProducts();
//         }
//
//         private void DeleteProductBtn_Click(object sender, RoutedEventArgs e)
//         {
//             var selected = ProductsGrid.SelectedItem;
//             if (selected == null)
//             {
//                 MessageBox.Show("Выберите товар для удаления");
//                 return;
//             }
//
//             int id = (int)selected.GetType().GetProperty("Id").GetValue(selected);
//             var product = db.Products.Find(id);
//
//             if (db.OrderItems.Any(oi => oi.ProductId == id))
//             {
//                 MessageBox.Show("Товар присутствует в заказе, удалить нельзя");
//                 return;
//             }
//
//             if (MessageBox.Show($"Удалить товар '{product.Name}'?", "Подтверждение", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
//             {
//                 db.Products.Remove(product);
//                 db.SaveChanges();
//                 LoadProducts();
//             }
//         }
//
//         private void UnblockUserBtn_Click(object sender, RoutedEventArgs e)
//         {
//             var blockedUsers = db.Users.Where(u => u.IsBlocked).ToList();
//             if (!blockedUsers.Any())
//             {
//                 MessageBox.Show("Нет заблокированных пользователей");
//                 return;
//             }
//
//             var unblockWindow = new UnblockWindow(db, blockedUsers);
//             if (unblockWindow.ShowDialog() == true)
//             {
//                 db.SaveChanges();
//                 MessageBox.Show("Пользователь разблокирован");
//             }
//         }
//
//         private void LogoutBtn_Click(object sender, RoutedEventArgs e)
//         {
//             currentUser = null;
//             UpdateUIForRole();
//         }
//     }
// }
// ----------------------------  App.xaml ----------------------------
// <Application x:Class="Store.App"
//              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//              StartupUri="MainWindow.xaml">
//     <Application.Resources>
//         <Style x:Key="ProductRowStyle" TargetType="DataGridRow">
//             <Style.Triggers>
//                 <DataTrigger Binding="{Binding Discount}" Value="0">
//                     <Setter Property="Background" Value="White"/>
//                 </DataTrigger>
//                 <DataTrigger Binding="{Binding Discount}" Value="15">
//                     <Setter Property="Background" Value="#2E8B57"/>
//                 </DataTrigger>
//                 <DataTrigger Binding="{Binding Stock}" Value="0">
//                     <Setter Property="Background" Value="LightBlue"/>
//                 </DataTrigger>
//             </Style.Triggers>
//         </Style>
//     </Application.Resources>
// </Application>
--------
// ---------------------------- LoginWindow.xaml ----------------------------
// <Window x:Class="Store.LoginWindow"
//         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//         Title="Авторизация" Height="250" Width="400" WindowStartupLocation="CenterScreen">
//
//     <Grid Margin="20">
//         <Grid.RowDefinitions>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//         </Grid.RowDefinitions>
//
//         <TextBlock Text="Вход в систему" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,20"/>
//
//         <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Логин:" Width="80" VerticalAlignment="Center"/>
//             <TextBox x:Name="LoginBox" Width="200"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Пароль:" Width="80" VerticalAlignment="Center"/>
//             <PasswordBox x:Name="PasswordBox" Width="200"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20">
//             <Button x:Name="LoginButton" Content="Войти" Width="80" Margin="5" Click="LoginButton_Click"/>
//             <Button x:Name="GuestButton" Content="Гость" Width="80" Margin="5" Click="GuestButton_Click"/>
//         </StackPanel>
//     </Grid>
// </Window>
------------
// ---------------------------- ФАЙЛ 7: LoginWindow.xaml.cs ----------------------------
// using System.Linq;
// using System.Windows;
//
// namespace Store
// {
//     public partial class LoginWindow : Window
//     {
//         private StoreContext db;
//         private int failedAttempts = 0;
//         private string currentLogin = null;
//         public User AuthenticatedUser { get; private set; }
//
//         public LoginWindow(StoreContext context)
//         {
//             InitializeComponent();
//             db = context;
//         }
//
//         private void LoginButton_Click(object sender, RoutedEventArgs e)
//         {
//             string login = LoginBox.Text;
//             string password = PasswordBox.Password;
//
//             var user = db.Users.FirstOrDefault(u => u.Login == login);
//
//             if (user == null)
//             {
//                 HandleFailedAttempt(null, login);
//                 return;
//             }
//
//             if (user.IsBlocked)
//             {
//                 MessageBox.Show("Вы заблокированы. Обратитесь к администратору",
//                                 "Доступ запрещён", MessageBoxButton.OK, MessageBoxImage.Warning);
//                 return;
//             }
//
//             if (user.Password != password)
//             {
//                 HandleFailedAttempt(user, login);
//                 return;
//             }
//
//             // Успешный вход
//             AuthenticatedUser = user;
//             DialogResult = true;
//             Close();
//         }
//
//         private void HandleFailedAttempt(User user, string login)
//         {
//             if (currentLogin != login)
//             {
//                 currentLogin = login;
//                 failedAttempts = 1;
//             }
//             else
//             {
//                 failedAttempts++;
//             }
//
//             MessageBox.Show($"Неверный логин или пароль. Попытка {failedAttempts} из 3",
//                             "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
//
//             if (user != null && failedAttempts >= 3)
//             {
//                 user.IsBlocked = true;
//                 db.SaveChanges();
//                 MessageBox.Show("Вы заблокированы. Обратитесь к администратору",
//                                 "Доступ запрещён", MessageBoxButton.OK, MessageBoxImage.Warning);
//                 Close();
//             }
//             else if (user == null && failedAttempts >= 3)
//             {
//                 MessageBox.Show("Вы заблокированы. Обратитесь к администратору",
//                                 "Доступ запрещён", MessageBoxButton.OK, MessageBoxImage.Warning);
//                 Close();
//             }
//         }
//
//         private void GuestButton_Click(object sender, RoutedEventArgs e)
//         {
//             AuthenticatedUser = null;
//             DialogResult = false;
//             Close();
//         }
//     }
// }
// ---------------------------- ФАЙЛ 8: ProductEditWindow.xaml ----------------------------
// <Window x:Class="Store.ProductEditWindow"
//         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//         Title="Товар" Height="500" Width="450" WindowStartupLocation="CenterScreen">
//
//     <Grid Margin="10">
//         <Grid.RowDefinitions>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="Auto"/>
//         </Grid.RowDefinitions>
//
//         <TextBlock Text="Редактирование товара" FontSize="16" FontWeight="Bold" Grid.Row="0" Margin="0,0,0,10"/>
//
//         <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="ID:" Width="100"/>
//             <TextBox x:Name="IdBox" IsReadOnly="True" Width="250"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Название:*" Width="100"/>
//             <TextBox x:Name="NameBox" Width="250"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Категория:*" Width="100"/>
//             <ComboBox x:Name="CategoryCombo" Width="250" DisplayMemberPath="Name"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="4" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Производитель:*" Width="100"/>
//             <ComboBox x:Name="ManufacturerCombo" Width="250" DisplayMemberPath="Name"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="5" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Цена:*" Width="100"/>
//             <TextBox x:Name="PriceBox" Width="250"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="6" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Количество:*" Width="100"/>
//             <TextBox x:Name="StockBox" Width="250"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="7" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Скидка (%)" Width="100"/>
//             <TextBox x:Name="DiscountBox" Text="0" Width="250"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="8" Orientation="Horizontal" Margin="0,5">
//             <TextBlock Text="Описание:" Width="100"/>
//             <TextBox x:Name="DescriptionBox" Width="250" Height="60" TextWrapping="Wrap"/>
//         </StackPanel>
//
//         <StackPanel Grid.Row="9" Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,20">
//             <Button x:Name="SaveBtn" Content="Сохранить" Width="100" Margin="5" Click="SaveBtn_Click"/>
//             <Button x:Name="CancelBtn" Content="Отмена" Width="100" Margin="5" Click="CancelBtn_Click"/>
//         </StackPanel>
//     </Grid>
// </Window>

Problem 2: Block doesn't save to database**
When a user enters the wrong password 3 times, I set IsBlocked = true. But after restarting the application, the user is not blocked anymore. It seems like the change is not saved to the database, or maybe I am not calling SaveChanges() correctly.
// ---------------------------- ФАЙЛ 9: ProductEditWindow.xaml.cs ----------------------------
// using System.Linq;
// using System.Windows;
//
// namespace Store
// {
//     public partial class ProductEditWindow : Window
//     {
//         private StoreContext db;
//         private Product editingProduct;
//
//         public ProductEditWindow(StoreContext context, Product product = null)
//         {
//             InitializeComponent();
//             db = context;
//             editingProduct = product ?? new Product();
//
//             CategoryCombo.ItemsSource = db.Categories.ToList();
//             ManufacturerCombo.ItemsSource = db.Manufacturers.ToList();
//
//             if (product != null)
//             {
//                 IdBox.Text = product.Id.ToString();
//                 NameBox.Text = product.Name;
//                 CategoryCombo.SelectedItem = db.Categories.FirstOrDefault(c => c.Id == product.CategoryId);
//                 ManufacturerCombo.SelectedItem = db.Manufacturers.FirstOrDefault(m => m.Id == product.ManufacturerId);
//                 PriceBox.Text = product.Price.ToString();
//                 StockBox.Text = product.Stock.ToString();
//                 DiscountBox.Text = product.Discount.ToString();
//                 DescriptionBox.Text = product.Description;
//             }
//         }
//
//         private void SaveBtn_Click(object sender, RoutedEventArgs e)
//         {
//             if (string.IsNullOrWhiteSpace(NameBox.Text))
//             {
//                 MessageBox.Show("Введите название товара");
//                 return;
//             }
//             if (CategoryCombo.SelectedItem == null)
//             {
//                 MessageBox.Show("Выберите категорию");
//                 return;
//             }
//             if (ManufacturerCombo.SelectedItem == null)
//             {
//                 MessageBox.Show("Выберите производителя");
//                 return;
//             }
//             if (!decimal.TryParse(PriceBox.Text, out decimal price) || price < 0)
//             {
//                 MessageBox.Show("Введите корректную цену");
//                 return;
//             }
//             if (!int.TryParse(StockBox.Text, out int stock) || stock < 0)
//             {
//                 MessageBox.Show("Введите корректное количество");
//                 return;
//             }
//             if (!int.TryParse(DiscountBox.Text, out int discount) || discount < 0 || discount > 100)
//             {
//                 MessageBox.Show("Скидка должна быть от 0 до 100");
//                 return;
//             }
//
//             editingProduct.Name = NameBox.Text;
//             editingProduct.CategoryId = ((Category)CategoryCombo.SelectedItem).Id;
//             editingProduct.ManufacturerId = ((Manufacturer)ManufacturerCombo.SelectedItem).Id;
//             editingProduct.Price = price;
//             editingProduct.Stock = stock;
//             editingProduct.Discount = discount;
//             editingProduct.Description = DescriptionBox.Text;
//
//             if (editingProduct.Id == 0)
//                 db.Products.Add(editingProduct);
//
//             db.SaveChanges();
//             DialogResult = true;
//             Close();
//         }
//
//         private void CancelBtn_Click(object sender, RoutedEventArgs e)
//         {
//             DialogResult = false;
//             Close();
//         }
//     }
// }
ФАЙЛ 10: OrdersWindow.xaml ----------------------------
// <Window x:Class="Store.OrdersWindow"
//         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
//         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
//         Title="Заказы" Height="450" Width="800" WindowStartupLocation="CenterScreen">
//
//     <Grid Margin="10">
//         <Grid.RowDefinitions>
//             <RowDefinition Height="Auto"/>
//             <RowDefinition Height="*"/>
//         </Grid.RowDefinitions>
//
//         <TextBlock Text="Список заказов" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" Margin="5"/>
//
//         <DataGrid x:Name="OrdersGrid" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True" Margin="0,10">
//             <DataGrid.Columns>
//                 <DataGridTextColumn Header="№ заказа" Binding="{Binding Id}" Width="80"/>
//                 <DataGridTextColumn Header="Клиент" Binding="{Binding User.FullName}" Width="150"/>
//                 <DataGridTextColumn Header="Дата заказа" Binding="{Binding OrderDate, StringFormat='dd.MM.yyyy'}" Width="100"/>
//                 <DataGridTextColumn Header="Статус" Binding="{Binding Status}" Width="100"/>
//                 <DataGridTextColumn Header="Адрес выдачи" Binding="{Binding PickupAddress}" Width="150"/>
//                 <DataGridTextColumn Header="Сумма" Binding="{Binding TotalAmount, StringFormat='{0:C}'}" Width="100"/>
//             </DataGrid.Columns>
//         </DataGrid>
//     </Grid>
// </Window>



Технологии для разработчиков | C#
Технологии для разработчиков | C#

Объектно-ориентированный и типобезопасный язык программирования, имеющий корни в языках семейства C и поддерживающий компонентно-ориентированное программирование.

Комментариев: 0 Без комментариев

1 ответ

Сортировать по: Наиболее полезные
  1. Lutter 0 Баллы репутации
    2026-06-15T18:34:55.88+00:00
     ---------------------------- ФАЙЛ 11: OrdersWindow.xaml.cs ----------------------------
    // using System.Linq;
    // using System.Windows;
    // using Microsoft.EntityFrameworkCore;
    //
    // namespace Store
    // {
    //     public partial class OrdersWindow : Window
    //     {
    //         private StoreContext db;
    //
    //         public OrdersWindow(StoreContext context)
    //         {
    //             InitializeComponent();
    //             db = context;
    //             LoadOrders();
    //         }
    //
    //         private void LoadOrders()
    //         {
    //             var orders = db.Orders
    //                 .Include(o => o.User)
    //                 .Include(o => o.OrderItems)
    //                 .ThenInclude(oi => oi.Product)
    //                 .ToList()
    //                 .Select(o => new
    //                 {
    //                     o.Id,
    //                     o.User,
    //                     o.OrderDate,
    //                     o.Status,
    //                     o.PickupAddress,
    //                     TotalAmount = o.OrderItems.Sum(oi => oi.Quantity * oi.Product.Price * (1 - oi.Product.Discount / 100m))
    //                 })
    //                 .ToList();
    //
    //             OrdersGrid.ItemsSource = orders;
    //         }
    //     }
    // }
     ---------------------------- ФАЙЛ 12: UnblockWindow.xaml ----------------------------
    // <Window x:Class="Store.UnblockWindow"
    //         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    //         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    //         Title="Разблокировка пользователей" Height="400" Width="500" WindowStartupLocation="CenterScreen">
    //
    //     <Grid>
    //         <Grid.RowDefinitions>
    //             <RowDefinition Height="*"/>
    //             <RowDefinition Height="Auto"/>
    //         </Grid.RowDefinitions>
    //
    //         <ListBox x:Name="UsersList" DisplayMemberPath="FullName" Margin="10" Grid.Row="0"/>
    //
    //         <Button x:Name="UnblockBtn" Content="Разблокировать выбранного" Click="UnblockBtn_Click"
    //                 Width="200" Height="35" Margin="10" Grid.Row="1" HorizontalAlignment="Center"/>
    //     </Grid>
    // </Window>
    ---------------------------- ФАЙЛ 13: UnblockWindow.xaml.cs ----------------------------
    // using System.Collections.Generic;
    // using System.Linq;
    // using System.Windows;
    //
    // namespace Store
    // {
    //     public partial class UnblockWindow : Window
    //     {
    //         private StoreContext db;
    //         private List<User> blockedUsers;
    //
    //         public UnblockWindow(StoreContext context, List<User> users)
    //         {
    //             InitializeComponent();
    //             db = context;
    //             blockedUsers = users;
    //             UsersList.ItemsSource = blockedUsers;
    //         }
    //
    //         private void UnblockBtn_Click(object sender, RoutedEventArgs e)
    //         {
    //             var selected = UsersList.SelectedItem as User;
    //             if (selected != null)
    //             {
    //                 selected.IsBlocked = false;
    //                 DialogResult = true;
    //                 Close();
    //             }
    //             else
    //             {
    //                 MessageBox.Show("Выберите пользователя для разблокировки");
    //             }
    //         }
    //     }
    // }
    ... and so on up to 13 blocks
    

    Этот ответ помог вам?

    Комментариев: 0 Без комментариев

Ваш ответ

Автор вопроса может устанавливать для ответов пометку "Принято", а модераторы — пометку "Рекомендуется". Благодаря этому пользователям становится проще понять, какой из ответов помог решить проблему автора.