780 likes | 966 Vues
ADO.NET ( A ctive D ata O bjects . NET) · tworzenie i przetwarzanie lokalnych, relacyjnych baz danych · współpraca z zewnętrznymi systemami zarządzania relacyjnymi bazami danych. Lokalna baza danych programu ( System.Data )
E N D
ADO.NET • ( Active Data Objects . NET) • · tworzenie i przetwarzanie lokalnych, • relacyjnych baz danych • · współpraca z zewnętrznymi systemami • zarządzania relacyjnymi bazami danych
Lokalna baza danych programu ( System.Data ) ·przestrzeń nazw System.Data klasy: DataColumn, DataRow, DataTable, DataGridView, DataSet ·DataColumn reprezentacja pojedynczej kolumny tabeli danych DataTable DataColumn colName = new DataColumn(); colName.DataType = Type.GetType("System.String"); // ReadOnly, Caption, ColumnName
·dodawanie do tabeli danych DataTable myTable = new DataTable("MyTable"); myTable.Columns.Add(colName); ·autoinkrementacja (przy tworzeniu wierszy) DataColumn empID = new DataColumn ("EmpID", Type.GetType("System.Int32")); empID.AutoIncrement = true; empID.AutoIncrementSeed = 100; empID.AutoIncrementStep = 10;
·DataRow wiersz tabeli danych DataTable DataTable empTable = new DataTable("Employees"); // columns EmpID, FirstName, LastName DataRow row = empTable.NewRow(); // ! row["FirstName"] = "John"; row["LastName"] = "Brown"; empTable.Rows.Add(row); // .DataRow.Delete() // .AcceptChanges(), .RejectChanges(), // .BeginEdit(), .EndEdit(), .CancelEdit() // .DataRow.Deleted , .Detached, .Modified // .New, .Unchanged
·DataTable tabela danych (relacja) ─ definiowanie i dodawanie kolumn ─ dodawanie i wypełnianie wierszy ─ określenie klucza głównego ( kluczy ) DataColumn[ ] PK = new DataColumn [ 1 ]; PK [ 0 ] = MyTable.Columns["EmpID"]; MyTable.PrimaryKey = PK; ─ wyświetlanie tabeli danych element DataGridView ─ przeciągnąć z palety elementów lub DataGridView MyGrid = new DataGridView(); ─następnie MyGrid.DataSource = MyTable;
·usuwanie wierszy try { MyTable.Rows[ rowNumber ].Delete(); MyTable.AcceptChanges(); } catch(Exception ex) { MessageBox.Show(ex.Message); }
·filtrowanie tabeli danych stringfilterStr = "FirstName='John'"; DataRow [ ] TheFirstName = MyTable.Select( filterStr );// ,ftSt2, ... -wyrażenie filtrujące ( wybrane operatory i funkcje) AND OR // operatory logiczne < <= > >= = <> IN LIKE // relacje + - * / % // operatory arytmetyczne *xxx xxx* %xxx xxx% // uogólnienia Sum Avg Min Max CountStDevVar // funkcje
·sortowanie tabeli danych TheFirstName = MyTable.Select ( filterStr, "LastName ASC"); // "LastName DESC" ·aktualizacja wierszy DataRow temp; for(int i=0; i < TheFirstName.Length; i++) { temp = TheFirstName[ i ]; temp["FirstName"] = "Ben"; }
·ograniczenia : Unique, Foreign Key • try • { • Table_A.Rows.Add(dr); • } • catch (ConstraintException ce) • { • MessageBox.Show (ce.Message ); • }
·zapis/odczyt do/z plików dyskowych - serializacja binarna - serializacja XML - czytak (tylko odczyt) DataTableReader dtR = dt.CreateDataReader(); while (dtR.Read()) for (int i = 0; i < dtReader.FieldCount; i++) { // ……… } dtR.Close(); DaBa
Inventory Customers CarID (k) Make Color PetName FirstName LastName CustID (k) Orders OrderID (k) CarID CustID ·DataSet relacyjna baza danych ·dowolna liczba tabel DataTablez określonymi powiązaniami
·tworzenie bazy danych // Data Tables private DataTable inventoryTable = new DataTable("Inventory"); private DataTable customersTable = new DataTable("Customers"); private DataTable ordersTable = new DataTable("Orders"); // make columns, set keys
// Data Set private DataSet carsDataSet = new DataSet("CarDataSet"); // add to data set carsDataSet.Tables.Add(ordersTable); carsDataSet.Tables.Add(customersTable); carsDataSet.Tables.Add(carsTable); // connect to data grid CarDataGrid.SetDataBinding (carsDataSet, "Inventory"); CustomerDataGrid.SetDataBinding (carsDataSet, "Customers");
·właściwości i funkcje klasy DataSet DataSetWork = newDataSet("CarsWorkshop"); Work.ExtendedProperties["TimeStamp"] = DateTime.Now; Work.ExtendedProperties["DataSetID"] =Guid.NewGuid(); Work.ExtendedProperties["Company"] = "Blue Skrew Super Shop";
▪serializacja do/z pliku XML .dataSet1.WriteXml("Plik.xml"); .dataSet1.WriteXml("Plik.xml",XmlWriteMode.WriteSchema); .dataSet1.ReadXml("Plik.xml"); .dataSet1.ReadXml("Plik.xml",XmlReadMode.ReadSchema);
▪ inne funkcje klasy DataSet .AcceptChanges() .Clear() .Clone() .Copy() .GetChanges() // tylko zmienione .HasChanges() .Merge() .RejectChanges() Grid
·definiowanie powiązań pomiędzy tabelami DataRelation dr = new DataRelation("CustomerOrder", // parent carsDataSet.Tables["Customers"]. Columns["CustID"], // child carsDataSet.Tables["Orders"]. Columns["CustID"]); carsDataSet.Relations.Add(dr); // Exception dr = new DataRelation("InventoryOrder", carsDataSet.Tables["Inventory"].Columns["CarID"], carsDataSet.Tables["Orders"]. Columns["CarID"]); carsDataSet.Relations.Add(dr);
·nawigowanie pomiędzy tabelami, np. wyszukanie opisu zamówienia i opisu samochodów na podstawie custID string strInfo = ""; DataRow drCust = null; DataRow[] drsOrder = null; int theCust = ... ; // custID // using custID, get the correct row drCust = carsDataSet.Tables["Customers"]. Rows[theCust]; strInfo += "Customer Name" + drCust["FirstName"] + "\n";
// navigate from customer table// to order table. drsOrder = drCust.GetChildRows (carsDataSet.Relations["CustomerOrder"]); // Get customer orders descriptions if(drsOrder != null) foreach(DataRow r in drsOrder) strInfo += "Order Number: " + r["OrderID"] + "\n";
// navigate from order table // to inventory table if(drsOrder != null) { DataRow[ ] drsInv = new DataRow [drsOrder.Length]; for(int i = 0; i < drsOrder.Length; ++i ) drsInv[i] = drsOrder[i].GetParentRows (carsDataSet.Relations["InventoryOrder"]); }
// Get cars descriptions if(drsInv.Length > 0) foreach(DataRow r in drsInv) { strInfo += "Make: " + r["Make"] + "\n"; strInfo += "Color: " + r["Color"] + "\n"; strInfo += "Pet Name: " + r["PetName"] + "\n"; } MessageBox.Show(strInfo + "Info based on cust ID"); CarDataSet PracSam
·LINQ to DataSet var ImPe = from osa in dataSet1.Tables["Osoby"].AsEnumerable() where osa["Imie"].ToString() == "Alicja"//osa["Imie"] : object selectnew { im = osa["Imie"], pe = osa["Pobory"] }; foreach (var os in ImPe) st += os.im + ", " + os.pe.ToString() + "\n"; LinqDS
Współpraca z DBMS ·tryb połączeniowy ·tryb bezpołączeniowy ·Entity Framework
·Dostawcy danych ( data providers ) Connection // połączenie Command // zapytanie SQL DataReader // czytak DataAdapter // odwzorowanie Parametr // parametr Transaction // transakcja
·Dostawcy danych ( data providers ) - wbudowani, np: - zewnętrzni www.sqlsummit.com/DataProv.htm
·wybór dostawcy na podstawie pliku konfiguracyjnego enumDataProvider { SqlServer, OleDb, Odbc, None } // Read the provider key. string dataProvString = ConfigurationManager.AppSettings["provider"]; // Transform string to enum. DataProvider dp = DataProvider.None; if (Enum.IsDefined(typeof(DataProvider), dataProvString)) dp = (DataProvider)Enum.Parse(typeof(DataProvider), dataProvString); else Console.WriteLine("Sorry, no provider exists!");
// App.config <configuration> <appSettings> <!-- This key value maps to one ofenum values--> <addkey="provider"value="SqlServer"/> </appSettings> </configuration>
·tryb połączeniowy - tworzenie i konfigurowanie obiektu połączenia - tworzenie i konfigurowanie obiektu poleceń - tworzenie czytaka przekazującego polecenie - odczytywanie kolejnych rekordów i ich przetwarzanie
- połączenie using (SqlConnection scn = newSqlConnection()) { scn.ConnectionString = // ciag par Property = Value@"DataSource=(local)\SQLEXPRESS;" + "Integrated Security=SSPI;" + "Initial Catalog=AutoLot"+ "Connect Timeout=50"; scn.Open(); }
·klasa SqlConnectionStringBuilder SqlConnectionStringBuilder cnStb = newSqlConnectionStringBuilder(); cnStb.InitialCatalog = ".\Database"; cnStb.DataSource = @"(local)"; // SQL Server cnStb.ConnectTimeout = 35; cnStb.IntegratedSecurity = true;
·odczytywanie stanu połączenia scn.DataSource scn.Database scn.ConnectionTimeout scn.State ............... // enum ConnectionState { Broken, Cloosed, Connecting, Executing, Fetching, Open }
- polecenie string strSQL = "Select * from Customers"; SqlCommandFirstCommand = newSqlCommand(strSQL,scn); // albo SqlCommand NextCommand = newSqlCommand( ); NextCommand.Connection = scn; NextCommand.CommandText = strSQL;
·odczytanie strumienia rekordów(bez nawigacji, bez zapisu) SqlDataReaderFirstReader; FirstDataReader = FirstCommand.ExecuteReader(); while ( FirstDataReader.Read() ) { .... FirstDataReader ["Make"] ..... } // można też przekazywać parametry // SqlParameter // i wykonywać procedury z bazy danych // FirstCommand.ExecuteNonQuery CarsDtReader
·indeksowanie pól SqlDataReader sdr = sCmd.ExecuteReader(); while (sdr.Read()) for(int i = 0; i < sdr.FieldCount; ++i) { Console.WriteLine("{0} = {1}", sdr.GetName(i), sdr.GetValue(i).ToString() ); }
·odczytywanie rekordów z wielu źródeł SqlCommand scmd = newSqlCommand( "SELECT * FROM Customers;" + "SELECT * FROM Orders", cns); SqlDataReader sdr = scmd.ExecuteReader(); do while (sdr.Read()) for(int i = 0; i < sdr.FieldCount; ++i) { // ............ } while(sdr.NextResult());
·tryb bezpołączeniowy - odwzorowanie bazy danych wDataSetDataAdapter - nie jest konieczne otwieranie i zamykanie połączenia z bazą danych - funkcje i właściwości klasy DataAdapter : Fill() // odwzorowanie wyniku zapytania SelectCommand InsertCommand UpdateCommand DeleteCommand Update( )
// odwzorowanie bezpośrednie string cnStr = "Integrated Security=SSPI;” + "Initial Catalog=AutoLot;" + @"DataSource=(local)\SQLEXPRESS"; DataSet ds = newDataSet("AutoLot"); SqlDataAdapter dAdapt = newSqlDataAdapter("Select * From Inventory", cnStr); dAdapt.Fill(ds, "Inventory");
// redefinicja nazw DataTableMapping custMap = dAdapt.TableMappings.Add( "Inventory", "Magazyn"); custMap.ColumnMappings.Add("CarID", "Identyfikator"); custMap.ColumnMappings.Add("Make", "Model");
// aktualizacja bazy danych DataSet DS = new DataSet("CarsDataSet"); dAdapt.Fill(DS, "Orders"); // dodawanie rekordów do tabeli zamówień DataRow[] DataRowArray = DS.Tables["Orders"]. Select(null, null, DataViewRowState.Added); dAdapt.Update( DataRowArray );
// generowanie pozostałych poleceń // w wersji domyślnej (śledzenie zmian) SqlDataAdapter dAdapt = newSqlDataAdapter("Select * From Orders", cnStr); dAdapt.Fill(DS, "Orders"); // . . . modyfikacja DS SqlCommandBuilder sqlB = newSqlCommandBuilder(dAdapt); dAdapt.Update(DS, "Orders"); Cars
·LINQ to SQL - pobieranie danych z DataSet ( zwykłe połączenie z bazą danych) var NaPe = from car in dataSet1.Tables["Inventory"].AsEnumerable() where (string)car["Color"] == "Red" selectnew { ma = (string)car["Make"], pe = (string)car["PetName"] }; Linq3
·Pobieranie danych • do obiektu specjalizowanej klasy • dziedziczącej z klasy DataSet • ( strongly typed Data Set ) • automatyczne dołączanie bazy danych • DataGridView / Choose Data Source / • Add Project Data Source / Database / Database • New Connection / Browse / Tables
powstaje klasa opakowująca bazę danych : • tabele, wiersze => klasy wewnętrzne tej klasy • kolumny => składowe klasy wierszy • powstaje klasa specjalizowanego adaptera danych • => wywoływany w momencie ładowania formy TDS
pobieranie danych • var MaCo = from car in carsDataSet.inventory • where car.Color == "Black" • selectnew { ma = car.Make, pt = car.PetName }; • aktualizacja • CarsDataSet.inventoryRow dr = carsDataSet.inventory.NewinventoryRow(); • dr.CarID = 387;dr.Color = "Black"; • dr.Make = "BMW";dr.PetName = "Mimi"; • carsDataSet.inventory.AddinventoryRow(dr);
// lub carsDataSet.inventory.AddinventoryRow( 444, "Alfa Romeo", "Gold", "Beauty"); // następnie inventoryTableAdapter.Update (carsDataSet.inventory);
dla elementu dataGridView wskazać jako źródło danych wybraną tabelę • => powstanie specjalizowany obiekt powiązania • aktualizacja na podstawie dataGridView • inventoryBindingSource.ResetBindings(false); • inventoryTableAdapter.Update • (carsDataSet.inventory); Linq4
ENTITY FRAMEWORK • Entity Data Model • współpraca bezpośrednio z SZBD ( bez kopiowania do DataSet )
mapa (entity) specjalizowana klasa odwzorowująca bazę danych i tworząca jej model • obsługa mapy (object services) współdziałanie programu z modelem (śledzenie zmian, aktualizacja, itp.) • klient mapy (entity client) nawiązywanie połączenia z bazą danych, generowanie zapytań SQL, itp.
trzy poziomy modeli (plik .edmx): • model koncepcyjny : definicja map i powiązań między mapami (.csdl) • model logiczny : odwzorowanie map i ich powiązań w tabele bazy danych (.msl) • model fizyczny : reprezentacja dostawcy danych (.ssdl)
klasa ObjectContext : klasa bazowa klasy definiującej mapę • using (OsobyEntities kontekst =new OsobyEntities()) • {dataGridView1.DataSource = kontekst.Lista; } • // Osoby : nazwa bazy danych • // Lista : nazwa tabeli • // • // Główne funkcje:AcceptAllChanges() AddObject() • DeleteObject() ExecuteFunction<T>() • GetObjectByKey() SaveChanges() • // Właściwości • ComandTimeout Connection • //Zdarzenia • SavingChanges