Pove z ivanje podataka sa kontrolama na formi data binding sa dlinq om
This presentation is the property of its rightful owner.
Sponsored Links
1 / 37

Pove z ivanje podataka sa kontrolama na formi - Data Binding sa DLINQ -om PowerPoint PPT Presentation


  • 90 Views
  • Uploaded on
  • Presentation posted in: General

Pove z ivanje podataka sa kontrolama na formi - Data Binding sa DLINQ -om. DLINQ omogućava lakše i elegantnije izvršavanje SQL upita u bazi podataka, nego korišćenjem klasa iz ADO.NET biblioteke

Download Presentation

Pove z ivanje podataka sa kontrolama na formi - Data Binding sa DLINQ -om

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Pove z ivanje podataka sa kontrolama na formi data binding sa dlinq om

Povezivanjepodataka sa kontrolama na formi - Data Binding sa DLINQ-om

  • DLINQ omogućava lakše i elegantnije izvršavanje SQL upita u bazi podataka, nego korišćenjem klasa iz ADO.NET biblioteke

  • DLINQ se nalazi iznad ADO.NET-a i koristi ga, tako da se može reći da DLINQ predstavlja jednu vrstu API-a za korišćenje ADO.NET-a

  • DLINQ ublažava razliku između SQL-a i objektne paradigme koja se koristi u C#-u i time čini blaži prelaz između razlike rada sa podacima u relacionoj bazi i objektnog koda programa

  • VS 2008 ima alat za podršku i automatizaciju rada sa DLINQ-om, Object Relational Designer


Object relational designer

Object Relational Designer

  • Object Relational Designer – ORL, omogućava automatsko povezivanje sa bazom podataka i kreiranje čitave infrastrukture klasa koje su potrebne za korišćenje DLINQ-a

  • ORL se ubacuje u WPF projekat iz menu-a Project / Add New Item... / Data / LINQ to SQL Classes, i zada se novo odgovarajuće ime

  • ORL automatski kreira novu klasu koja nasleđuje od DataContext klase i čije ime se automatski formira sa prefiksom zadatog imena ORL i sufiksom DataContext

  • Ako se ORL nazove Northwind, onda je ime nove klase NorthwindDataContext


Object relational designer1

Object Relational Designer

  • Da bi ORL mogao da automatski kreira entity klase koje odgovaraju tabelama baze podataka, neophodno je povezati odgovarajuću bazu podataka iz VS2008

  • Povezivanje VS i baze podataka se vrši iz prozora Server Explorer (SE)

  • U gornjem delu prozora SE se nalazi ikona Data Connection koja se selektuje i iz menu-a Tools / Connect to Database... se dobija dijalog box za podešavanje konekcije sa bazom podataka

  • Za konekciju sa bazom je potrebno da postoji baza podataka kao file tipa *.mdf koji može biti već povezan sa SQL Express serverom – levi deo sledeceg slide-a ili ga tek treba povezati – Attach a data base file – desni deo sledeceg slide-a


Object relational designer2

Object Relational Designer

  • Kada se poveže baza podataka sa VS, onda mogu da se uvezu tabele iz povezane baze podataka za koje će ORL automatski da kreira odgovarajuće entity klase

  • Ispod ikone Data Connection u VS se nalazi ikona nove baze podataka koja je povezana, a ispod koje se nalazi kolekcija Tabels baze podataka

  • Otvaranjem ove kolecije – klik na + sa leve strane, dobija se spisak svih tabela u povezanoj bazi

  • Sa desne strane se odabere prozor ORL – Northwind.dbml i jednostavno se prevuku željene tabele u prozor ORL


Object relational designer3

Object Relational Designer

  • Za svaku prevučenu tabelu u prozor ORL se automatski kreira odgovarajuća entity klasa čiji je naziv jednak nazivu odgovarajuće tabele

  • U prevučenim tabelama se mogu brisati polja koja nisu potrebna i koja se neće koristiti u radu sa tabelama baze podataka

  • Osim navedenih tabela, ORL automatski kreira i konfiguracioni file app.config koji se dodaje projektu

  • File app.config je xml dokument koji sadrži connection string koji definiše konekciju sa bazom podataka i omogućava da se promene detalji konekcije bez izmene u kodu aplikacije

  • Od app.config se kreira file application.exe.configgde je application naziv aplikacije i distribuira se zajedno sa application.exe u istom folder-u


App config xml file

app.config xml file

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

</configSections>

<connectionStrings>

<add name="Suppliers.Properties.Settings.NorthwindConnectionString"

connectionString="Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True“providerName="System.Data.SqlClient" />

</connectionStrings>

</configuration>

  • File pod nazivom application.exe.configima potpuno isti sadržaj kao i gore prikazani sadržaj file-a app.config, koji treba da se nalazi u istom folderu kao i prevedeni application.exe file.

  • Parametri konekcije se mogu promeniti u xml application.exe.configfile-u bez izmene application.exe


Izgled prozora aplikacije

Izgled prozora aplikacije


Selekcija dobavlja a suppliers

Selekcija dobavljača - suppliers


Definisanje izgleda stavki u combo box u za dobavlja e suppliers

Definisanje izgleda stavki u combo box-u za dobavljače - suppliers

<Window x:Class=”WpfApplication1.Window1”

...>

<Window.Resources>

<DataTemplate x:Key=”SuppliersTemplate”>

<StackPanel Orientation=”Horizontal”>

<TextBlock Text=”{Binding Path=SupplierID}” />

<TextBlock Text=” : “ />

<TextBlock Text=”{Binding Path=CompanyName}” />

<TextBlock Text=” : “ />

<TextBlock Text=”{Binding Path=ContactName}” />

</StackPanel>

</DataTemplate>

</Window.Resources>

<Grid>

...

</Grid>

</Window>

<ComboBox ... Name=”suppliersList” IsSynchronizedWithCurrentItem=”True”

ItemsSource=”{Binding}” ItemTemplate=”{StaticResource SuppliersTemplate}” />


Definisanje izgleda stavki u list box u za proizvode products

Definisanje izgleda stavki u list box-u za proizvode - products

<ListView ... Name=”productsList” ...>

<ListView.View>

<GridView>

<GridView.Columns>

<GridViewColumn Width=”75” Header=”Product ID”

DisplayMemberBinding=”{Binding Path=ProductID}” />

<GridViewColumn Width=”225” Header=”Name”

DisplayMemberBinding=”{Binding Path=ProductName}” />

<GridViewColumn Width=”135” Header=”Quantity Per Unit”DisplayMemberBinding=”{Binding Path=QuantityPerUnit}” />

<GridViewColumn Width=”75” Header =”Unit Price”

DisplayMemberBinding=”{Binding Path=UnitPrice}” />

</GridView.Columns>

</GridView>

</ListView.View>

</ListView>


Klasa za konverziju vrednosti

Klasa za konverziju vrednosti

[ValueConversion(typeof(string), typeof(decimal?))]

class PriceConverter : IValueConverter

{

public object Convert(object value, Type targetType, object parameter,

System.Globalization.CultureInfo culture)

{

if (value != null)

return String.Format(“{0:C}”, value);

else

return “”;

}

public object ConvertBack(object value, Type targetType, object parameter,

System.Globalization.CultureInfo culture)

{

throw new NotImplementedException();

}

}

  • Klasa za konverziju PriceConverter iz tipa decimal? koji je nullable u entity klasi – može da fali, u tip String u kontroli ListView na formi


Objekat klase priceconverter kao resurs

Objekat klase PriceConverter kao resurs

<Window x:Class=”Suppliers.SupplierInfo”

...

xmlns:app=”clr-namespace:Suppliers”

...>

<Window.Resources>

<app:PriceConverter x:Key=”priceConverter” />

...

</Window.Resources>

...

</Window>

<GridViewColumn ... Header =”Unit Price” DisplayMemberBinding=

“{Binding Path=UnitPrice, Converter={StaticResource priceConverter}}” />

  • U XAML kodu se sa:

  • <app:PriceConverter x:Key=”priceConverter” />

  • Kreira objekat priceConverter klase PriceConverter kao resurs koji se koristi u GridViewColumn


Dinami ko povezivanje kontrole combobox sa entity klasom

Dinamičko povezivanje kontrole ComboBox sa entity klasom

<Window x:Class=”Suppliers.SupplierInfo”

...

Title=”Supplier Information” ... Loaded=”Window_Loaded”>

...

</Window>

public partial class SupplierInfo : Window

{

private NorthwindDataContext ndc = null;

private Supplier supplier = null;

private BindingList<Product> productsInfo = null;

...

}

private void Window_Loaded(object sender, RoutedEventArgs e)

{

ndc = new NorthwindDataContext();

this.suppliersList.DataContext = ndc.Suppliers;

}


Dinami ko povezivanje kontrole combobox sa entity klasom1

Dinamičko povezivanje kontrole ComboBox sa entity klasom

private void suppliersList_SelectionChanged(object sender,

SelectionChangedEventArgs e)

{

supplier = this.suppliersList.SelectedItem as Supplier;

IList list = ((IListSource)supplier.Products).GetList();

productsInfo = list as BindingList<Product>;

this.productsList.DataContext = productsInfo;

}

  • EntitySet<Product> klasaimplementiraIListSource interface, koji deklariše GetList metod za kopiranje podataka iz entity set-au IList objekat list

  • BindingList implementira interface-e koji deklarišu događaje INotifyPropertyChangingiINotifyPropertyChangedna koje reaguju povezane kontrole i vrednosti koje pokazuju se update-uju - ažuriraju


A uriranje podataka sa dlinq om

Ažuriranje podataka sa DLINQ-om

  • Do sada kreirana aplikacija omogućava povezani prikaz podataka o proizvođačima - ComboBox i proizvodima – ListBox

  • Odnos je M : 1 – jedan proizvođač više proizvoda, i jedan proizvod jedan proizvođač

  • Promena – ažuriranje podataka nije moguća

  • Podaci iz baze su povezani sa kontrolama koje ih prikazuju preko Table kolekcija

  • Promena podataka u kontrolama menja podatke u povezanim entity klasama – u memoriji, ali ne menja podatke u bazi


A uriranje podataka sa dlinq om1

Ažuriranje podataka sa DLINQ-om

NorthwindDataContext ndc = new NorthwindDataContext();

Product product = ndc.Products.Single(p => p.ProductID == 14);

product.ProductName = “Bean Curd”;

ndc.SubmitChanges();

ndc.Refresh(RefreshMode.OverwriteCurrentValues, ndc.Products);

  • Podaci u bazi se menjaju preko SQL ili DLINQ upita

  • Metod SubmitChanges klase ContextData upisuje promene u bazu

  • Metod Refresh vraća podatke iz baze u Table kolekcije, tj. tako se mogu poništiti promene u kolekciji koje još nisu upisane u bazu

  • Metod Refresh može da prihvati više kolekcija – parameters kao drugi parametar


A uriranje podataka sa dlinq om2

Ažuriranje podataka sa DLINQ-om

  • Metod SubmitChanges klase ContextData upisuje sve promene u bazu

  • Ako neka promena dovede do greške upisa u bazu, sve se vraća na prethodno stanje, tj. vrši se transakcija i ako bilo koja od operacija izmene ne uspe, sve se vraća na prethodno stanje – roll back

  • Pri tome se podaci u kolekcijama entity klasa ne menjaju

  • Pre ponovnog pokušaja ažuriranja treba promeniti podatke koji su doveli do neuspeha

  • Ako sve izmene u bazi uspeju, transakcija se izvršava – commit, i promene se upisuju u bazu


Konflikti pri a uriranju podataka

Konflikti pri ažuriranju podataka

  • Pri ažuriranju podataka može doći do međusobnog konflikta promena istih podataka koje unose dva korisnika

  • Ako dva korisnika menjaju iste podatke u bazi onda može da dođe do izgubljenih podataka koje je uneo jedan od korisnika

  • Metod SubmitChanges može da otkrije kada se to desi i da aktivira ChangeConflictException

  • SvojstvoChangeConflicts objekta klase DataContextje kolekcija objekata tipa ObjectChangeConflict

  • SvojstvoIsDeletedje boolean i ukazuje da li drugi korisnik pokušava da briše podatke koji se menjaju


Konflikti pri a uriranju podataka1

Konflikti pri ažuriranju podataka

  • Zatim svojstvo MemberConflictskoje je kolekcija objekata tipa MemberChangeConflict koji sadrže korespodentnu vrednost podatka u memoriji, tekuću vrednost podatka u bazi kao i prvobitnu vrednost podatka u bazi koja je učitana

  • Na osnovu toga se može kreirati procedura razrešenja konflikta – koja od te tri vrednosti će se prihvatiti

  • Moguće je i da korisnik aplikacije odluči šta da se radi u cilju rezolucije konflikta

  • KlasaObjectChangeConflict sadrži method Resolve


M ethod resolve k lase objectchangeconflict

Method Resolve klaseObjectChangeConflict

  • Method Resolveima argument tipa enumeracije RefreshModečije vrednosti ukazuju na način rezolucije konflikta

  • RefreshMode.KeepCurrentValues – tekuće vrednosti u memoriji prepisuju konfliktne vrednosti – tekući korisnik je pobednik konflikta

  • RefreshMode.OverwriteCurrentValue – tekuće vrednosti iz memorije se prepisuju vrednostima iz baze – tekući korisnik je gubitnik konflikta

  • RefreshMode.KeepChanges – izmenjene vrednosti od oba korisnika se merdžuju, ako su u različitim kolonama – oba korisnika su pobednici konflikta


Primer rezolucije konflikta

Primer rezolucije konflikta

try

{

ndc.SubmitChanges();

}

catch (ChangeConflictException)

{

foreach (ObjectChangeConflict conflict in ndc.ChangeConflicts)

{

Foreach (MemberChangeConflict changeConflict in conflict.MemberConflicts)

{

Console.WriteLine(“Conflict Details”);

Console.WriteLine(“Original value retrieved from database: {0}”,

changeConflict.OriginalValue.ToString());

Console.WriteLine(“Current value in database: {0}”,

changeConflict.DatabaseValue.ToString());

Console.WriteLine(“Current value in memory: {0}”,

changeConflict.CurrentValue.ToString());

}

conflict.Resolve(RefreshMode.OverwriteCurrentValues);

}

}


M ethod resolve k lase objectchangeconflict1

Method Resolve klaseObjectChangeConflict

  • Kolekcija ChangeConflicts klaseDataContext sadrži ResolveAll metod koji omogućava da se ista RefreshMode vrednost primeni za rezoluciju svih konflikata

  • Ako se metod

  • ndc.SubmitChanges(ConflictMode.ContinueOnConflict);

  • Pozove sa ConflictMode.ContinueOnConflict vrednošću enumeracije, onda se prvo probaju sve izmene nakon čega se aktivira ChangeConflictException ako ima jedan ili više konflikata

  • Ako se metod SubmitChanges zove bez tog argumenta, onda se generiše ChangeConflictException pri svakom konfliktu

  • Podrazumevano ponašanje je sa vrednošću kolekcije ConflictMode.FailOnFirstConfl ict.


Dodavanje i brisanje podataka

Dodavanje i brisanje podataka

NorthwindDataContext ndc = new NorthwindDataContext(...);

Table<Product> products = ndc.Products;

Product newProduct = new Product() {ProductName = “New Product”, ... };

products.Add(newProduct);

...

ndc.SubmitChanges):

  • Posle poziva metoda SubmitChanges, DataContext objekat će generisatiSQL INSERT naredbu za svaku novu stavku u Table kolekciji

Product product = products.Single(p => p.ProductID == 14);

products.Remove(product);

...

ndc.SubmitChanges):

  • Posle poziva metoda SubmitChanges, DataContextobjekat će generisati SQL DELETEnaredbu za svaku izbrisanu stavku u Table kolekciji


A uriranje proizvoda

Ažuriranje proizvoda

private void productsList_KeyDown(object sender, KeyEventArgs e)

{

switch (e.Key)

{

case Key.Enter: editProduct(this.productsList.SelectedItem as Product);

break;

case Key.Insert: addNewProduct();

break;

case Key.Delete: deleteProduct(this.productsList.SelectedItem as Product);

break;

}

}

  • Metod productsList ispituje pritisnutu tipku tastature kada se selektuje stavka liste productsList preko svojstva Key objekta e klase KeyEventArgs koja sadrži vrednosti enumeracije System.Windows.Input.Key na osnovu čega se poziva odgovarajući metod za ažuriranje


Deleteproduct method

deleteProduct method

private void deleteProduct(Product prod)

{

MessageBoxResult response = MessageBox.Show(“Delete “ + prod.ProductName,

“Confirm”, MessageBoxButton.YesNo, MessageBoxImage.Question,

MessageBoxResult.No);

if (response == MessageBoxResult.Yes)

{

supplier.Products.Remove(prod);

productsInfo.Remove(prod);

this.saveChanges.IsEnabled = true;

}

}

  • supplier je objekat entity klase koja služi za povezivanje sa tabelom, Products je kolekcija entity objekata za datog supplier-a – dobavljača

  • productsInfo je BindingList koja služi za povezivanje sa ListView kontrolom productsList


Izmena i dodavanje proizvoda

Izmena i dodavanje proizvoda

  • Za izmenu i dodavanje proizvoda potrebno je kreirati novu pomoćnu formu sa poljima proizvoda koja se dodaju / menjaju


Izgled forme za editovanje proizvoda

Izgled forme za editovanje proizvoda


Pove z ivanje podataka sa kontrolama na formi data binding sa dlinq om

<Window x:Class="Suppliers.ProductForm"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="ProductForm" Height="225" Width="515" ResizeMode="NoResize">

<Grid>

<Label Height="23" Margin="17,20,0,0" Name="label1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120">Product Name</Label>

<Label Margin="17,60,0,0" Name="label2" Height="23" VerticalAlignment="Top" Width="120" HorizontalAlignment="Left">Quantity Per Unit</Label>

<Label Margin="17,100,0,0" Name="label3" Height="23" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120">Unit Price</Label>

<TextBox Height="21" Margin="130,24,0,0" Name="productName" VerticalAlignment="Top" Width="340" HorizontalAlignment="Left" />

<TextBox Height="21" Margin="130,64,0,0" Name="quantityPerUnit" VerticalAlignment="Top" HorizontalAlignment="Left" Width="340" />

<TextBox Height="21" Margin="130,104,0,0" Name="unitPrice" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120" />

<Button Height="23" HorizontalAlignment="Left" Margin="130,150,0,0" Name="ok" VerticalAlignment="Top" Width="75" Click="ok_Click">OK</Button>

<Button Height="23" HorizontalAlignment="Left" Margin="300,150,0,0" Name="cancel" VerticalAlignment="Top" Width="75" IsCancel="True">Cancel</Button>

</Grid>

</Window>


Pove z ivanje podataka sa kontrolama na formi data binding sa dlinq om

private void ok_Click(object sender, RoutedEventArgs e)

{

if (String.IsNullOrEmpty(this.productName.Text))

{

MessageBox.Show(“The product must have a name”, “Error”,

MessageBoxButton.OK, MessageBoxImage.Error);

return;

}

decimal result;

If (!Decimal.TryParse(this.unitPrice.Text, out result))

{

MessageBox.Show(“The price must be a valid number”, “Error”,

MessageBoxButton.OK, MessageBoxImage.Error);

return;

}

if (result < 0)

{

MessageBox.Show(“The price must not be less than zero”, “Error”,

MessageBoxButton.OK, MessageBoxImage.Error);

return;

}

this.DialogResult = true;

}


Dodavanje novog proizvoda

Dodavanje novog proizvoda

private void addNewProduct()

{

ProductForm pf = new ProductForm();

pf.Title = “New Product for “ + supplier.CompanyName;

if (pf.ShowDialog().Value)

{

Product newProd = new Product();

newProd.SupplierID = supplier.SupplierID;

newProd.ProductName = pf.productName.Text;

newProd.QuantityPerUnit = pf.quantityPerUnit.Text;

newProd.UnitPrice = Decimal.Parse(pf.unitPrice.Text);

supplier.Products.Add(newProd);

productsInfo.Add(newProd);

this.saveChanges.IsEnabled = true;

}

}


Izmena podataka o proizvodu

Izmena podataka o proizvodu

private void editProduct(Product prod)

{

ProductForm pf = new ProductForm();

pf.Title = “Edit Product Details”;

pf.productName.Text = prod.ProductName;

pf.quantityPerUnit.Text = prod.QuantityPerUnit;

pf.unitPrice.Text = prod.UnitPrice.ToString();

if (pf.ShowDialog().Value)

{

prod.ProductName = pf.productName.Text;

prod.QuantityPerUnit = pf.quantityPerUnit.Text;

prod.UnitPrice = Decimal.Parse(pf.unitPrice.Text);

this.saveChanges.IsEnabled = true;

}

}


Upis izmena u bazu

Upis izmena u bazu

private void saveChanges_Click(object sender, RoutedEventArgs e)

{

try

{

ndc.SubmitChanges();

saveChanges.IsEnabled = false;

}

catch (Exception ex)

{

MessageBox.Show(ex.Message, “Error saving changes”);

}

}


  • Login