Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
Ez a lépésenkénti útmutató bemutatja, hogyan hozhat létre egy egyszerű, SQLite-adatbázissal támogatott Windows Forms-(WinForms-) alkalmazást. Az alkalmazás az Entity Framework Core (EF Core) használatával tölti be az adatokat az adatbázisból, nyomon követi az adatok módosításait, és megőrzi ezeket a módosításokat az adatbázisba.
Az útmutatóban szereplő képernyőképek és kódrészletek a Visual Studio 2022 17.3.0-s verzióból származnak.
Jótanács
A cikk mintáját a GitHubtekintheti meg.
Előfeltételek
A bemutató befejezéséhez telepítenie kell a Visual Studio 2022 17.3 vagy újabb verzióját a kijelölt .NET desktop környezet mellett. A Visual Studio legújabb verziójának telepítéséről további információt a Visual Studio telepítése című témakörben talál.
Az alkalmazás létrehozása
A Visual Studio megnyitása
A kezdési ablakban válassza az Új projekt létrehozása lehetőséget.
Válassza a Windows Forms appot , majd a Tovább gombot.
A következő képernyőn adjon nevet a projektnek( például GetStartedWinForms), és válassza a Tovább gombot.
A következő képernyőn válassza ki a használni kívánt .NET-verziót. Ez az útmutató a .NET 7-tel lett létrehozva, de a későbbi verziókkal is működnie kell.
Válassza a Létrehozás elemet.
Az EF Core NuGet-csomagok telepítése
Kattintson a jobb gombbal a megoldásra, és válassza a NuGet-csomagok kezelése megoldás szintjén...
Válassza a Tallózás lapot, és keressen rá a "Microsoft.EntityFrameworkCore.Sqlite" kifejezésre.
Válassza ki a Microsoft.EntityFrameworkCore.Sqlite csomagot.
Ellenőrizze a GetStartedWinForms projektet a jobb oldali panelen.
Válassza ki a legújabb verziót. A kiadás előtti verzió használatához győződjön meg arról, hogy az Include prerelease (Előzetes verzió belefoglalása) jelölőnégyzet be van jelölve.
Kattintson a Telepítés gombra
Megjegyzés:
A Microsoft.EntityFrameworkCore.Sqlite az EF Core SQLite-adatbázissal való használatához használt "adatbázis-szolgáltató" csomag. Hasonló csomagok érhetők el más adatbázisrendszerekhez is. Az adatbázis-szolgáltatói csomagok telepítése automatikusan biztosítja az EF Core és az adatbázisrendszer használatához szükséges összes függőséget. Ez magában foglalja a Microsoft.EntityFrameworkCore alapcsomagot is.
Modell definiálása
Ebben az útmutatóban a "Code First" használatával implementálunk egy modellt. Ez azt jelenti, hogy az EF Core az Ön által definiált C#-osztályok alapján hozza létre az adatbázistáblákat és -sémákat. Az adatbázisséma kezelése című témakörből megtudhatja, hogyan használhat helyette egy meglévő adatbázist.
Kattintson a jobb gombbal a projektre, és válassza a Hozzáadás, majd az Osztály lehetőséget egy új osztály hozzáadásához.
Használja a fájlnevet
Product.cs, és cserélje le az osztály kódját a következőre:using System.ComponentModel; namespace GetStartedWinForms; public class Product { public int ProductId { get; set; } public string? Name { get; set; } public int CategoryId { get; set; } public virtual Category Category { get; set; } = null!; }Ismételje meg a létrehozást
Category.csa következő kóddal:using Microsoft.EntityFrameworkCore.ChangeTracking; namespace GetStartedWinForms; public class Category { public int CategoryId { get; set; } public string? Name { get; set; } public virtual ObservableCollectionListSource<Product> Products { get; } = new(); }
Az Products osztály tulajdonságát Category és az Category osztály tulajdonságát Product "navigációnak" nevezzük. Az EF Core-ban a navigációk két entitástípus közötti kapcsolatot határoznak meg. Ebben az esetben a navigáció arra a Product.Category kategóriára hivatkozik, amelyhez egy adott termék tartozik. Hasonlóképpen, a Category.Products gyűjtemény navigációs sávja egy adott kategóriához tartozó összes terméket tartalmazza.
Jótanács
Windows Forms használata esetén a ObservableCollectionListSource, amely megvalósítja a IListSource-t, használható gyűjteménynavigációkhoz. Ez nem szükséges, de javítja a kétirányú adatkötési élményt.
A DbContext definiálása
Az EF Core-ban a modell entitástípusainak konfigurálására és az adatbázissal való interakció munkamenetként való kezelésére szolgál az EF Core-ban származtatott DbContext osztály. A legegyszerűbb esetben egy DbContext osztály:
- A modell minden entitástípusának tulajdonságait tartalmazza
DbSet. - Felülírja a
OnConfiguringmetódust, amely az adatbázis-szolgáltatót és a kapcsolati sztringet konfigurálja használatra. További információ: DbContext konfigurálása .
Ebben az esetben a DbContext osztály felülbírálja az OnModelCreating alkalmazás néhány mintaadatának megadására szolgáló módszert is.
Adjon hozzá egy új ProductsContext.cs osztályt a projekthez a következő kóddal:
using Microsoft.EntityFrameworkCore;
namespace GetStartedWinForms;
public class ProductsContext : 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");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Category>().HasData(
new Category { CategoryId = 1, Name = "Cheese" },
new Category { CategoryId = 2, Name = "Meat" },
new Category { CategoryId = 3, Name = "Fish" },
new Category { CategoryId = 4, Name = "Bread" });
modelBuilder.Entity<Product>().HasData(
new Product { ProductId = 1, CategoryId = 1, Name = "Cheddar" },
new Product { ProductId = 2, CategoryId = 1, Name = "Brie" },
new Product { ProductId = 3, CategoryId = 1, Name = "Stilton" },
new Product { ProductId = 4, CategoryId = 1, Name = "Cheshire" },
new Product { ProductId = 5, CategoryId = 1, Name = "Swiss" },
new Product { ProductId = 6, CategoryId = 1, Name = "Gruyere" },
new Product { ProductId = 7, CategoryId = 1, Name = "Colby" },
new Product { ProductId = 8, CategoryId = 1, Name = "Mozzela" },
new Product { ProductId = 9, CategoryId = 1, Name = "Ricotta" },
new Product { ProductId = 10, CategoryId = 1, Name = "Parmesan" },
new Product { ProductId = 11, CategoryId = 2, Name = "Ham" },
new Product { ProductId = 12, CategoryId = 2, Name = "Beef" },
new Product { ProductId = 13, CategoryId = 2, Name = "Chicken" },
new Product { ProductId = 14, CategoryId = 2, Name = "Turkey" },
new Product { ProductId = 15, CategoryId = 2, Name = "Prosciutto" },
new Product { ProductId = 16, CategoryId = 2, Name = "Bacon" },
new Product { ProductId = 17, CategoryId = 2, Name = "Mutton" },
new Product { ProductId = 18, CategoryId = 2, Name = "Pastrami" },
new Product { ProductId = 19, CategoryId = 2, Name = "Hazlet" },
new Product { ProductId = 20, CategoryId = 2, Name = "Salami" },
new Product { ProductId = 21, CategoryId = 3, Name = "Salmon" },
new Product { ProductId = 22, CategoryId = 3, Name = "Tuna" },
new Product { ProductId = 23, CategoryId = 3, Name = "Mackerel" },
new Product { ProductId = 24, CategoryId = 4, Name = "Rye" },
new Product { ProductId = 25, CategoryId = 4, Name = "Wheat" },
new Product { ProductId = 26, CategoryId = 4, Name = "Brioche" },
new Product { ProductId = 27, CategoryId = 4, Name = "Naan" },
new Product { ProductId = 28, CategoryId = 4, Name = "Focaccia" },
new Product { ProductId = 29, CategoryId = 4, Name = "Malted" },
new Product { ProductId = 30, CategoryId = 4, Name = "Sourdough" },
new Product { ProductId = 31, CategoryId = 4, Name = "Corn" },
new Product { ProductId = 32, CategoryId = 4, Name = "White" },
new Product { ProductId = 33, CategoryId = 4, Name = "Soda" });
}
}
Ezen a ponton mindenképpen hozza létre a megoldást .
Vezérlők hozzáadása az űrlaphoz
Az alkalmazás megjeleníti a kategóriák listáját és a termékek listáját. Ha az első listában kiválaszt egy kategóriát, a második lista az adott kategóriához tartozó termékeket jeleníti meg. Ezek a listák módosíthatók termékek és kategóriák hozzáadására, eltávolítására vagy szerkesztésére, és ezek a módosítások a Mentés gombra kattintva menthetők az SQLite-adatbázisba.
Módosítsa a főűrlap nevét a következőre
Form1MainForm: .
És módosítsa a címet "Termékek és kategóriák" értékre.
Az Eszközkészlet használatával adjon hozzá két
DataGridViewvezérlőt egymás mellé rendezve.
Az első
DataGridViewközött módosítsa a nevet a következőredataGridViewCategories: .A második tulajdonságok között a
DataGridViewváltoztassa meg a Nevet adataGridViewProducts-re.Az eszközkészletet is használva adjon hozzá egy vezérlőt
Button.Nevezze el a gombot
buttonSave, és adja meg a "Mentés" szöveget. Az űrlapnak a következőképpen kell kinéznie:
Adatkötés
A következő lépés, hogy a modellben található Product és Category típusokat összekapcsoljuk a DataGridView vezérlőkkel. Ez az EF Core által betöltött adatokat a vezérlőkhöz köti, így az EF Core által követett entitások szinkronban maradnak a vezérlőkben megjelenőkkel.
Kattintson a Tervező művelet ikonra az első
DataGridView. Ez a vezérlő jobb felső sarkában található apró gomb.
Ekkor megnyílik a műveletlista, amelyből elérhető a kiválasztott adatforrás legördülő listája. Még nem hoztunk létre adatforrást, ezért lépjen az aljára, és válassza az Új objektum adatforrás hozzáadása... lehetőséget.
A Kategória gombra kattintva objektum-adatforrást hozhat létre a kategóriák számára, és kattintson az OK gombra.
Jótanács
Ha itt nem jelennek meg adatforrástípusok, győződjön meg róla, hogy
Product.cs,Category.csésProductsContext.cshozzá lett adva a projekthez és a megoldás le lett fordítva.Most az Adatforrás kiválasztása legördülő menü tartalmazza az imént létrehozott objektum-adatforrást. Bontsa ki az Egyéb adatforrások, majd a Projekt adatforrások elemet, és válassza a Kategória lehetőséget.
A második
DataGridViewtermékhez lesz kötve. A felső szintűProducttípushoz való kötés helyett azonban inkább azProductselsőCategorykötésből származóDataGridViewnavigációhoz lesz kötve. Ez azt jelenti, hogy ha az első nézetben kiválaszt egy kategóriát, az adott kategória termékei automatikusan a második nézetben lesznek használatban.A második elemnél a
DataGridViewhasználva válassza az Adatforrás kiválasztása lehetőséget, majd bontsa ki acategoryBindingSourceelemet, és válassza aProductslehetőséget.
A megjelenített adatok konfigurálása
Alapértelmezés szerint a kötött típusok minden tulajdonságához létrejön egy oszlop a DataGridView-ben. Ezen tulajdonságok értékeit is szerkesztheti a felhasználó. Egyes értékek, például az elsődleges kulcsértékek azonban elméletileg csak olvashatók, ezért nem szerkeszthetők. Emellett egyes tulajdonságok, például az CategoryId idegenkulcs-tulajdonság és a Category navigáció nem hasznosak a felhasználó számára, ezért rejtve kell lenniük.
Jótanács
Gyakori, hogy egy valós alkalmazásban elrejti az elsődleges kulcstulajdonságokat. Itt láthatóak maradnak, hogy könnyen láthatóvá tegyék, hogy az EF Core mit csinál a színfalak mögött.
Kattintson a jobb gombbal az elsőre
DataGridView, és válassza az Oszlopok szerkesztése... parancsot.
Állítsa be az
CategoryIdoszlopot, amely az elsődleges kulcsot ábrázolja, írásvédetté, majd kattintson az OK gombra.
Kattintson a jobb gombbal a második
DataGridViewelemre, és válassza az Oszlopok szerkesztése... parancsot. Tegye aProductIdoszlopot írásvédetté, távolítsa el aCategoryIdés aCategoryoszlopokat, majd kattintson az OK gombra.
Csatlakozás az EF Core-hoz
Az alkalmazásnak most már kis mennyiségű kódra van szüksége az EF Core adatkötött vezérlőkhöz való csatlakoztatásához.
MainFormA kód megnyitásához kattintson a jobb gombbal a fájlra, és válassza a Kód megtekintése parancsot.
Adjon hozzá egy privát mezőt a
DbContextmunkamenet tárolásához, és adjon hozzá felülbírálásokat aOnLoadésOnClosingmetódusokhoz. A kódnak így kell kinéznie:
using Microsoft.EntityFrameworkCore;
using System.ComponentModel;
namespace GetStartedWinForms
{
public partial class MainForm : Form
{
private ProductsContext? dbContext;
public MainForm()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.dbContext = new ProductsContext();
// Uncomment the line below to start fresh with a new database.
// this.dbContext.Database.EnsureDeleted();
this.dbContext.Database.EnsureCreated();
this.dbContext.Categories.Load();
this.categoryBindingSource.DataSource = dbContext.Categories.Local.ToBindingList();
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
this.dbContext?.Dispose();
this.dbContext = null;
}
}
}
A OnLoad metódus meghívása az űrlap betöltésekor történik. Jelenleg
- Létrejön egy
ProductsContextpéldány, amely az alkalmazás által megjelenített termékek és kategóriák betöltésére és változásainak nyomon követésére szolgál. -
EnsureCreatedADbContextmeghívásával hozza létre az SQLite-adatbázist, ha még nem létezik. Ez egy gyors módja annak, hogy adatbázist hozzon létre alkalmazások prototípusának vagy tesztelésének során. Ha azonban a modell megváltozik, az adatbázist törölni kell, hogy újra létre lehessen hozni. (AEnsureDeletedsor megjegyzés nélkül is törölhető, így egyszerűen törölheti és újra létrehozhatja az adatbázist az alkalmazás futtatásakor.) Ehelyett az EF Core Migrations használatával módosíthatja és frissítheti az adatbázissémát anélkül, hogy adatokat veszítené el. -
EnsureCreatedaz új adatbázist is feltölti a metódusbanProductsContext.OnModelCreatingmeghatározott adatokkal. - A
Loadbővítménymetódus az adatbázis összes kategóriájának betöltésére szolgál aDbContext. Ezeket az entitásokat mostantól nyomon követi aDbContextrendszer, amely észleli a kategóriák felhasználó általi szerkesztésekor végrehajtott módosításokat. - A
categoryBindingSource.DataSourcetulajdonság inicializálva lesz azokhoz a kategóriákhoz, amelyeket aDbContextrendszer nyomon követ. Ez úgy történik, hogy aLocal.ToBindingList()Categoriestulajdonságon meghívjuk aDbSet-t.Localhozzáférést biztosít a nyomon követett kategóriák helyi nézetéhez, és az események összekapcsolva biztosítják, hogy a helyi adatok szinkronban legyenek a megjelenített adatokkal, és fordítva.ToBindingList()ezeket az adatokat úgy teszi elérhetővé, mint egyIBindingList, amelyet a Windows Forms adatkötés értelmez.
A OnClosing metódus meghívása az űrlap bezárásakor történik. A folyamat során a DbContext erőforrások elengedésére kerül sor, biztosítva, hogy minden adatbázis-erőforrás felszabaduljon, és a dbContext mező null értéket kap, hogy az ne legyen újból használható.
A Termékek nézet feltöltése
Ha az alkalmazás ezen a ponton indul el, akkor a következőhöz hasonlóan kell kinéznie:
Figyelje meg, hogy a kategóriák be lettek töltve az adatbázisból, de a terméktábla üres marad. A Mentés gomb szintén nem működik.
A termékek táblájának feltöltéséhez az EF Core-nak be kell töltenie a termékeket a kiválasztott kategória adatbázisából. Ennek eléréséhez:
A főűrlap tervezőjében válassza ki a
DataGridViewkategóriákat.A Tulajdonságok
DataGridViewterületen válassza ki az eseményeket (a villám gombot), majd kattintson duplán a SelectionChanged eseményre.
Ez létrehoz egy csonkot a fő űrlapkódban ahhoz, hogy egy esemény aktiválódjon, amikor a kategóriaválasztás megváltozik.
Töltse ki az esemény kódját:
private void dataGridViewCategories_SelectionChanged(object sender, EventArgs e)
{
if (this.dbContext != null)
{
var category = (Category)this.dataGridViewCategories.CurrentRow.DataBoundItem;
if (category != null)
{
this.dbContext.Entry(category).Collection(e => e.Products).Load();
}
}
}
Ebben a kódban, ha egy aktív (nem null) DbContext munkamenet van, akkor lekérjük a Category példányt, amely a jelenleg kiválasztott DataViewGrid sorhoz van kötve. (Ez akkor fordulhat null elő, ha a nézetben az utolsó sor van kijelölve, amely új kategóriák létrehozására szolgál.) Ha van egy kijelölt kategória, akkor a DbContext felhasználónak be kell töltenie az adott kategóriához társított termékeket. Ezt a következő módon végezheti el:
- Példány lekérése
EntityEntryCategory(dbContext.Entry(category)) - Tudatni az EF Core-sal, hogy a
Productsgyűjtemény navigációs sávján szeretnénkCategoryműködni (.Collection(e => e.Products)) - Végül pedig azt mondja az EF Core-nak, hogy be szeretnénk tölteni az adatbázisból származó termékgyűjteményt (
.Load();)
Jótanács
Amikor Load meghívásra kerül, az EF Core csak akkor fér hozzá az adatbázishoz a termékek betöltéséhez, ha azok még nem lettek betöltve.
Ha az alkalmazás most újra fut, akkor a megfelelő termékeket kell betöltenie, amikor kiválaszt egy kategóriát:
Módosítások mentése
Végül a Mentés gomb csatlakoztatható az EF Core-hoz, hogy a termékeken és kategóriákon végzett módosítások az adatbázisba legyenek mentve.
A főűrlap tervezőjében válassza a Mentés gombot.
A Tulajdonságok
Buttonterületen válassza ki az eseményeket (a villám gombot), és kattintson duplán a Kattintás eseményre.
Töltse ki az esemény kódját:
private void buttonSave_Click(object sender, EventArgs e)
{
this.dbContext!.SaveChanges();
this.dataGridViewCategories.Refresh();
this.dataGridViewProducts.Refresh();
}
Ez a kód meghívja SaveChanges a DbContextkódot, amely menti az SQLite-adatbázis módosításait. Ha nem történt módosítás, akkor ez egy no-op, és nem történik adatbázis-hívás. A mentés után a DataGridView vezérlők frissülnek. Ennek az az oka, hogy az EF Core beolvassa a létrehozott elsődleges kulcsértékeket az adatbázisból származó új termékekhez és kategóriákhoz. A hívás Refresh frissíti a megjelenítést ezekkel a létrehozott értékekkel.
A végleges alkalmazás
Itt található a fő űrlap teljes kódja:
using Microsoft.EntityFrameworkCore;
using System.ComponentModel;
namespace GetStartedWinForms
{
public partial class MainForm : Form
{
private ProductsContext? dbContext;
public MainForm()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.dbContext = new ProductsContext();
// Uncomment the line below to start fresh with a new database.
// this.dbContext.Database.EnsureDeleted();
this.dbContext.Database.EnsureCreated();
this.dbContext.Categories.Load();
this.categoryBindingSource.DataSource = dbContext.Categories.Local.ToBindingList();
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
this.dbContext?.Dispose();
this.dbContext = null;
}
private void dataGridViewCategories_SelectionChanged(object sender, EventArgs e)
{
if (this.dbContext != null)
{
var category = (Category)this.dataGridViewCategories.CurrentRow.DataBoundItem;
if (category != null)
{
this.dbContext.Entry(category).Collection(e => e.Products).Load();
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
this.dbContext!.SaveChanges();
this.dataGridViewCategories.Refresh();
this.dataGridViewProducts.Refresh();
}
}
}
Az alkalmazás most már futtatható, és a termékek és kategóriák hozzáadhatók, törölhetők és szerkeszthetők. Figyelje meg, hogy ha az alkalmazás bezárása előtt a Mentés gombra kattint, az alkalmazás újrakezdésekor a rendszer az adatbázisban tárolja a módosításokat, és újra betölti őket. Ha a Mentés gombra nem kattint, a módosítások elvesznek az alkalmazás újrakezdésekor.
Jótanács
Új kategória vagy termék hozzáadható a DataViewControl vezérlőelem alján lévő üres sor használatával. A sorokat a Del billentyűt lenyomva lehet törölni.
Mentés előtt
Mentés után
Figyelje meg, hogy a hozzáadott kategória és termékek elsődleges kulcsértékei a Mentés gombra kattintáskor lesznek feltöltve.