Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu adım adım izlenecek yol, POCO türlerini WPF denetimlerine "main-detail" biçiminde bağlamayı gösterir. Uygulama, veritabanındaki verilerle nesneleri doldurmak, değişiklikleri izlemek ve verileri veritabanında kalıcı hale getirmek için Entity Framework API'lerini kullanır.
Model, bire çok ilişkisine katılan iki tür tanımlar: Kategori (asıl\ana) ve Ürün (bağımlı\ayrıntı). WPF veri bağlama çerçevesi, ilgili nesneler arasında gezintiyi etkinleştirir: ana görünümde satırların seçilmesi, ayrıntı görünümünün ilgili alt verilerle güncelleştirilmesine neden olur.
Bu kılavuzdaki ekran görüntüleri ve kod listeleri Visual Studio 2019 16.6.5'ten alınmıştır.
Tip
Bu makalenin örneğini GitHubüzerinde görüntüleyebilirsiniz.
Pre-Requisites
Bu kılavuzu tamamlamak için Visual Studio 2019 16.3 veya üzerini .NET masaüstü iş yükü seçili olarak yüklemeniz gerekir. Visual Studio'nun en son sürümünü yüklemekle ilgili daha fazla bilgi için, Visual Studio'yu yüklemebölümüne bakın.
Uygulamayı Oluşturma
- Visual Studio’yu açın
- Başlangıç penceresinde Yeni proje oluştur'u seçin.
- "WPF" araması yapın, WPF Uygulaması (.NET) öğesini ve ardından İleri'yi seçin.
- Sonraki ekranda projeye getStartedWPF gibi bir ad verin ve Oluştur'u seçin.
Entity Framework NuGet paketlerini yükleme
Çözüme sağ tıklayın ve Çözüm için NuGet Paketlerini Yönet... seçeneğini belirleyin.
Arama kutusuna yazın
entityframeworkcore.sqlite.Microsoft.EntityFrameworkCore.Sqlite paketini seçin.
Sağ bölmede projeyi denetleyin ve Yükle'ye tıklayın
entityframeworkcore.proxiesaraması yapmak ve yüklemek için adımları yineleyin.
Note
Sqlite paketini yüklediğinizde ilgili Microsoft.EntityFrameworkCore temel paketini otomatik olarak aşağı çekti. Microsoft.EntityFrameworkCore.Proxies paketi "gecikmeli yükleme" verileri için destek sağlar. Bu, alt varlıklara sahip varlıklarınız olduğunda, ilk yüklemede yalnızca ebeveyn varlıkların getirildiği anlamına gelir. Proxy'ler, alt varlıklara erişim girişimini algıladığında, bu varlıkları istek üzerine otomatik olarak yükler.
Model Tanımlama
Bu kılavuzda "önce kod" kullanarak bir model uygulayacaksınız. Bu, EF Core'un tanımladığınız C# sınıflarını temel alan veritabanı tablolarını ve şemasını oluşturacağı anlamına gelir.
Yeni bir sınıf ekleyin. Adı verin: Product.cs ve şu şekilde doldurun:
Product.cs
namespace GetStartedWPF
{
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
}
Ardından adlı Category.cs bir sınıf ekleyin ve aşağıdaki kodla doldurun:
Category.cs
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace GetStartedWPF
{
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<Product>
Products
{ get; private set; } =
new ObservableCollection<Product>();
}
}
Category sınıfındaki Products özelliği ve Product sınıfındaki Category özelliği gezinti özellikleridir. Entity Framework'te gezinti özellikleri, iki varlık türü arasındaki ilişkide gezinmek için bir yol sağlar.
Varlıkları tanımlamaya ek olarak, DbContext'ten türetilen ve DbSet<TEntity> özelliklerini kullanıma sunan bir sınıf tanımlamanız gerekir. DbSet<TEntity> özellikleri, bağlama modele hangi türleri eklemek istediğinizi bildirir.
DbContext türetilmiş türünün bir örneği, çalışma zamanında varlık nesnelerini yönetir. Bu, nesneleri veritabanındaki verilerle doldurma, değişiklik izleme ve verileri veritabanında kalıcı hale getirme gibi işlemleri içerir.
Aşağıdaki tanım ile projeye yeni ProductContext.cs bir sınıf ekleyin:
ProductContext.cs
using Microsoft.EntityFrameworkCore;
namespace GetStartedWPF
{
public class ProductContext : DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnConfiguring(
DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(
"Data Source=products.db");
optionsBuilder.UseLazyLoadingProxies();
}
}
}
- , EF Core'a
DbSethangi C# varlıklarının veritabanına eşlenmesi gerektiğini bildirir. - EF Core'un
DbContextyapılandırılmasının çeşitli yolları vardır. Bunlar hakkında bilgi edinmek için bkz. DbContext yapılandırma. - Bu örnekte, bir SQLite veri dosyasını belirtmek için
OnConfiguringgeçersiz kılma kullanılır. -
UseLazyLoadingProxiesÇağrısı EF Core'a gecikmeli yükleme gerçekleştirmesini bildirir, bu nedenle üst öğeden erişildiğinde alt varlıklar otomatik olarak yüklenir.
Projeyi derlemek için CTRL+SHIFT+B tuşlarına basın veya Derleme Çözümü Oluştur'a > gidin.
Tip
Veritabanınızı ve EF Core modellerinizi eşitlenmiş durumda tutmanın farklı olduğunu öğrenin: Veritabanı Şemalarını Yönetme.
Gecikmeli Yükleme
Category sınıfındaki Products özelliği ve Product sınıfındaki Category özelliği gezinti özellikleridir. Entity Framework Core'da gezinti özellikleri, iki varlık türü arasındaki ilişkide gezinmek için bir yol sağlar.
EF Core, gezinti özelliğine ilk kez erişişiniz için veritabanından ilgili varlıkları otomatik olarak yükleme seçeneği sunar. Bu yükleme türüyle (gecikmeli yükleme olarak adlandırılır), her gezinti özelliğine ilk kez erişişinizde, içerik henüz bağlamda değilse veritabanında ayrı bir sorgu yürütüleceğini unutmayın.
"Düz Eski C# Nesnesi" (POCO) varlık türlerini kullanırken, EF Core çalışma zamanı sırasında türetilmiş ara sunucu türlerinin örneklerini oluşturarak ve ardından yükleme kancasını eklemek için sınıflarınızdaki sanal özellikleri geçersiz kılarak gecikmeli yükleme sağlar. İlgili nesnelerin yavaş yüklenmesini sağlamak için, gezinti özelliği alıcılarını genel ve sanal (Visual Basic'te Geçersiz Kılınabilir ) olarak bildirmeniz ve sınıfınızın korumalı olmaması gerekir (Visual Basic'te NotOverridable ). Önce Veritabanı kullanılırken, gezinme özellikleri gecikmeli yüklemeyi etkinleştirmek için otomatik olarak sanal hale getirilir.
Nesneyi Denetimlere Bağlama
Modelde tanımlanan sınıfları bu WPF uygulaması için veri kaynakları olarak ekleyin.
Ana formu açmak için Çözüm Gezgini'nde MainWindow.xaml öğesine çift tıklayın
XAML'yi düzenlemek için XAML sekmesini seçin.
Etiketi açtıktan
Windowhemen sonra EF Core varlıklarına bağlanmak için aşağıdaki kaynakları ekleyin.<Window x:Class="GetStartedWPF.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:local="clr-namespace:GetStartedWPF" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded"> <Window.Resources> <CollectionViewSource x:Key="categoryViewSource"/> <CollectionViewSource x:Key="categoryProductsViewSource" Source="{Binding Products, Source={StaticResource categoryViewSource}}"/> </Window.Resources>Bu, "ana" kategoriler için kaynak oluşturur ve "ayrıntı" ürünler için ikinci bir kaynak hazırlar.
Ardından, açma
Gridetiketinden sonra XAML'nize aşağıdaki işaretlemeyi ekleyin.<DataGrid x:Name="categoryDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding Source={StaticResource categoryViewSource}}" Margin="13,13,43,229" RowDetailsVisibilityMode="VisibleWhenSelected"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding CategoryId}" Header="Category Id" Width="SizeToHeader" IsReadOnly="True"/> <DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="*"/> </DataGrid.Columns> </DataGrid>CategoryIdöğesinin veritabanı tarafından atandığı içinReadOnlyolarak ayarlandığını ve değiştirilemediğini dikkate alın.
Ayrıntılar Tablosu Ekleme
Kategorileri görüntülemek için kılavuz mevcut olduğuna göre, ayrıntılar kılavuzu ürünleri göstermek için eklenebilir. Bunu, kategoriler Grid öğesinden sonra, DataGrid öğesinin içine ekleyin.
MainWindow.xaml
<DataGrid x:Name="productsDataGrid" AutoGenerateColumns="False"
EnableRowVirtualization="True"
ItemsSource="{Binding Source={StaticResource categoryProductsViewSource}}"
Margin="13,205,43,108" RowDetailsVisibilityMode="VisibleWhenSelected"
RenderTransformOrigin="0.488,0.251">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding CategoryId}"
Header="Category Id" Width="SizeToHeader"
IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding ProductId}" Header="Product Id"
Width="SizeToHeader" IsReadOnly="True"/>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="*"/>
</DataGrid.Columns>
</DataGrid>
Son olarak, Save düğmesi ekleyin ve Button_Click için tıklama olayını bağlayın.
<Button Content="Save" HorizontalAlignment="Center" Margin="0,240,0,0"
Click="Button_Click" Height="20" Width="123"/>
Tasarım görünümünüz şu şekilde görünmelidir:
Veri Etkileşimlerini İşleyen Kod Ekleme
Ana pencereye bazı olay işleyicileri eklemenin zamanı geldi.
XAML penceresinde Window< öğesine tıklayarak> ana pencereyi seçin.
Özellikler penceresinde sağ üstteki Olaylar'ı seçin, ardından Yüklenen etiketinin sağındaki metin kutusuna çift tıklayın.
Bu işlem sizi formun kodun arka yüzüne götürür; şimdi ProductContext kullanarak veri erişimi gerçekleştirmek için kodu düzenleyeceğiz. Kodu aşağıda gösterildiği gibi güncelleştirin.
Kod, uzun süreli çalışan ProductContext örneğini bildirir.
ProductContext nesnesi, verileri sorgulamak ve veritabanına kaydetmek için kullanılır.
Dispose() örnekteki ProductContext yöntemi, geçersiz kılınan OnClosing yönteminden çağrılır. Kod açıklamaları her adımın ne yaptığını açıklar.
MainWindow.xaml.cs
using Microsoft.EntityFrameworkCore;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
namespace GetStartedWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly ProductContext _context =
new ProductContext();
private CollectionViewSource categoryViewSource;
public MainWindow()
{
InitializeComponent();
categoryViewSource =
(CollectionViewSource)FindResource(nameof(categoryViewSource));
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// this is for demo purposes only, to make it easier
// to get up and running
_context.Database.EnsureCreated();
// load the entities into EF Core
_context.Categories.Load();
// bind to the source
categoryViewSource.Source =
_context.Categories.Local.ToObservableCollection();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// all changes are automatically tracked, including
// deletes!
_context.SaveChanges();
// this forces the grid to refresh to latest values
categoryDataGrid.Items.Refresh();
productsDataGrid.Items.Refresh();
}
protected override void OnClosing(CancelEventArgs e)
{
// clean up database connections
_context.Dispose();
base.OnClosing(e);
}
}
}
Note
Kod, veritabanını ilk çalıştırmada derlemek için EnsureCreated() bir çağrı kullanır. Bu demolar için kabul edilebilir, ancak üretim uygulamalarında şemanızı yönetmek için migrasyonlara bakmanız gerekir. Kod ayrıca yerel bir SQLite veritabanı kullandığından zaman uyumlu olarak yürütülür. Üretim senaryoları genellikle uzak sunucu içeriyorsa, Load ve SaveChanges yöntemlerinin zaman uyumsuz sürümlerini kullanmayı göz önünde bulundurun.
WPF Uygulamasını Test Edin
F5 tuşuna basarak veya Hata Ayıklama Hata Ayıklamayı > Başlat'ı seçerek uygulamayı derleyin ve çalıştırın. Veritabanı adlı products.dbbir dosyayla otomatik olarak oluşturulmalıdır. Bir kategori adı girin ve Enter tuşuna basın, ardından alt kılavuza ürün ekleyin. Kaydet'e tıklayın ve veritabanı tarafından sağlanan kimliklerle tablo yenilendiğini izleyin. Satırı vurgulayın ve satırı kaldırmak için Sil'e basın.
Kaydet'e tıkladığınızda varlık silinir.
Mülk Değişikliği Bildirimi
Bu örnek, varlıkları kullanıcı arabirimiyle eşitlemek için dört adıma dayanır.
- İlk çağrı
_context.Categories.Load(), kategori verilerini yükler. - Yavaş yüklenen proxy'ler bağımlı ürün verilerini yükler.
- EF Core'un yerleşik değişiklik izlemesi, çağrıldığında
_context.SaveChanges()eklemeler ve silmeler dahil olmak üzere varlıklarda gerekli değişiklikleri yapar. -
DataGridView.Items.Refresh()'ye yapılan çağrılar, yeni oluşturulan kimliklerle zorunlu bir yeniden yükleme başlatır.
Bu, başlangıç örneğimizde işe yarar, ancak diğer senaryolar için ek kod gerektirebilirsiniz. WPF denetimleri, varlıklarınızdaki alanları ve özellikleri okuyarak kullanıcı arabirimini işler. Kullanıcı arabiriminde (UI) bir değeri düzenlediğinizde, bu değer varlığınıza geçirilir. Bir özelliğin değerini doğrudan varlığınızda değiştirdiğinizde (örneğin, veritabanından yüklerken), WPF kullanıcı arabirimindeki değişiklikleri hemen yansıtmaz. İşleme altyapısına değişiklikler bildirilmelidir. Proje bunu manuel olarak Refresh() çağırarak yaptı. Bu bildirimi otomatikleştirmenin kolay bir yolu , INotifyPropertyChanged arabirimini uygulamaktır. WPF bileşenleri arabirimi otomatik olarak algılar ve değişiklik olaylarına kaydolacaktır. Varlık bu olayları başlatmakla sorumludur.
Tip
Değişiklikleri işleme hakkında daha fazla bilgi edinmek için bkz. Özellik değişikliği bildirimini uygulama.
Sonraki Adımlar
DbContext Yapılandırma hakkında daha fazla bilgi edinin.