Udostępnij za pośrednictwem


Praca z kolumnami obliczanymi (C#)

Autor: Scott Mitchell

Pobierz plik PDF

Podczas tworzenia tabeli bazy danych program Microsoft SQL Server umożliwia zdefiniowanie obliczonej kolumny, której wartość jest obliczana na podstawie wyrażenia, które zwykle odwołuje się do innych wartości w tym samym rekordzie bazy danych. Takie wartości są tylko do odczytu w bazie danych, co wymaga szczególnych zagadnień podczas pracy z elementami TableAdapters. Z tego samouczka dowiesz się, jak sprostać wyzwaniom związanym z obliczonymi kolumnami.

Wprowadzenie

Program Microsoft SQL Server umożliwia obliczane kolumny, które są kolumnami, których wartości są obliczane na podstawie wyrażenia, które zwykle odwołuje się do wartości z innych kolumn w tej samej tabeli. Na przykład model danych śledzenia czasu może mieć tabelę o nazwie ServiceLog z kolumnami, takimi jak ServicePerformed, EmployeeID, Ratei Duration, między innymi. Podczas gdy kwota należna na element usługi (jest stawką pomnożoną przez czas trwania) może być obliczana za pośrednictwem strony internetowej lub innego interfejsu programowego, może być przydatna do uwzględnienia kolumny w ServiceLog tabeli o nazwie , AmountDue która zgłosiła te informacje. Tę kolumnę można utworzyć jako normalną kolumnę, ale trzeba ją zaktualizować w dowolnym momencie Rate zmiany wartości kolumny lub Duration . Lepszym rozwiązaniem jest utworzenie AmountDue kolumny obliczonej przy użyciu wyrażenia Rate * Duration. W ten sposób program SQL Server automatycznie oblicza AmountDue wartość kolumny za każdym razem, gdy odwołuje się do niego w zapytaniu.

Ponieważ obliczona wartość kolumny jest określana przez wyrażenie, takie kolumny są tylko do odczytu i dlatego nie mogą mieć przypisanych do nich wartości w INSERT instrukcjach lub UPDATE . Jednak gdy obliczone kolumny są częścią głównego zapytania dla klasy TableAdapter, które używa instrukcji AD-hoc SQL, są one automatycznie uwzględniane w automatycznie generowanych INSERT instrukcjach i UPDATE . W związku z tym należy zaktualizować kwerendy INSERT i UPDATE właściwości tableAdapter, InsertCommand UpdateCommand aby usunąć odwołania do wszystkich obliczonych kolumn.

Jednym z wyzwań dotyczących używania obliczonych kolumn z tabelą TableAdapter, która korzysta z instrukcji SQL ad hoc, jest to, że zapytania tableAdapter i INSERT zapytania UPDATE są automatycznie generowane po zakończeniu pracy kreatora konfiguracji tableAdapter. W związku z tym obliczone kolumny ręcznie usunięte z INSERT zapytań i UPDATE zostaną ponownie wyświetlone, jeśli kreator zostanie ponownie uruchomiony. Chociaż tableAdapters, które korzystają z procedur składowanych, nie cierpią z powodu tej kruchości, mają własne dziwactwa, które zajmiemy się w kroku 3.

W tym samouczku dodamy kolumnę obliczeniową do Suppliers tabeli w bazie danych Northwind, a następnie utworzymy odpowiednią tabelę TableAdapter, aby pracować z tą tabelą i jej obliczoną kolumną. Nasza klasa TableAdapter będzie używać procedur składowanych zamiast instrukcji ad hoc SQL, dzięki czemu nasze dostosowania nie zostaną utracone, gdy zostanie użyty kreator konfiguracji tableAdapter.

Zacznijmy!

Krok 1. Dodawanie kolumny obliczeniowejSuppliersdo tabeli

Baza danych Northwind nie ma żadnych kolumn obliczeniowych, więc musimy dodać jedną kolumnę. Na potrzeby tego samouczka dodajmy kolumnę obliczeniową do Suppliers tabeli o nazwie FullContactName , która zwraca nazwę kontaktu, tytuł i firmę, dla której pracują w następującym formacie: ContactName (ContactTitle, CompanyName). Ta obliczona kolumna może być używana w raportach podczas wyświetlania informacji o dostawcach.

Zacznij od otwarcia Suppliers definicji tabeli, klikając prawym przyciskiem myszy tabelę Suppliers w Eksploratorze serwera i wybierając polecenie Otwórz definicję tabeli z menu kontekstowego. Spowoduje to wyświetlenie kolumn tabeli i ich właściwości, takich jak ich typ danych, niezależnie od tego, czy zezwalają na NULL wartości i tak dalej. Aby dodać obliczoną kolumnę, zacznij od wpisania nazwy kolumny do definicji tabeli. Następnie wprowadź wyrażenie w polu tekstowym (Formuła) w sekcji Specyfikacja kolumny obliczeniowej w okno Właściwości kolumny (zobacz Rysunek 1). Nazwij obliczoną kolumnę FullContactName i użyj następującego wyrażenia:

ContactName + ' (' + CASE WHEN ContactTitle IS NOT NULL THEN 
    ContactTitle + ', ' ELSE '' END + CompanyName + ')'

Pamiętaj, że ciągi można łączyć w języku SQL przy użyciu + operatora . Instrukcja CASE może być używana jak warunkowa w tradycyjnym języku programowania. W powyższym wyrażeniu CASE instrukcja może być odczytywana jako: Jeśli ContactTitle nie NULL jest, wyprowadź ContactTitle wartość połączoną z przecinkiem, w przeciwnym razie nic nie emituj. Aby uzyskać więcej informacji na temat przydatności instrukcjiCASE, zobacz Instrukcje SQLCASE.

Uwaga

Zamiast używać instrukcji CASE w tym miejscu, moglibyśmy również użyć ISNULL(ContactTitle, '')metody . ISNULL(checkExpression, replacementValue) Zwraca wartość checkExpression , jeśli nie ma wartości NULL, w przeciwnym razie zwraca wartość replacementValue. Chociaż w tym wystąpieniu działa element ISNULL lub CASE , istnieje bardziej skomplikowane scenariusze, w których elastyczność instrukcji CASE nie może być zgodna z elementem ISNULL.

Po dodaniu tej obliczonej kolumny ekran powinien wyglądać jak zrzut ekranu na rysunku 1.

Dodawanie obliczonej kolumny o nazwie FullContactName do tabeli Dostawców

Rysunek 1. Dodawanie kolumny obliczeniowej o nazwie FullContactName do Suppliers tabeli (kliknij, aby wyświetlić obraz pełnowymiarowy)

Po nazewnictwie obliczonej kolumny i wprowadzeniu jej wyrażenia zapisz zmiany w tabeli, klikając ikonę Zapisz na pasku narzędzi, naciskając Ctrl+S lub przechodząc do menu Plik i wybierając polecenie Zapisz Suppliers.

Zapisanie tabeli powinno odświeżyć Eksploratora serwera, w tym właśnie dodaną kolumnę na Suppliers liście kolumn tabeli. Ponadto wyrażenie wprowadzone w polu tekstowym (Formuła) automatycznie dostosuje się do równoważnego wyrażenia, które usuwa niepotrzebne odstępy, otacza nazwy kolumn nawiasami ([]) i zawiera nawiasy, aby bardziej jawnie pokazać kolejność operacji:

(((([ContactName]+' (')+case when [ContactTitle] IS NOT NULL 
    then [ContactTitle]+', ' else '' end)+[CompanyName])+')')

Aby uzyskać więcej informacji na temat kolumn obliczeniowych w programie Microsoft SQL Server, zapoznaj się z dokumentacją techniczną. Zapoznaj się również z przewodnikiem Instrukcje: Określanie kolumn obliczeniowych , aby zapoznać się z przewodnikiem krok po kroku tworzenia kolumn obliczeniowych.

Uwaga

Domyślnie obliczone kolumny nie są fizycznie przechowywane w tabeli, ale zamiast tego są ponownie obliczane za każdym razem, gdy są przywoływane w zapytaniu. Zaznaczając pole wyboru Jest utrwalone, można jednak poinstruować program SQL Server, aby fizycznie przechowywał obliczoną kolumnę w tabeli. Dzięki temu indeks może zostać utworzony w obliczonej kolumnie, co może poprawić wydajność zapytań używających obliczonej wartości kolumny w swoich WHERE klauzulach. Aby uzyskać więcej informacji, zobacz Tworzenie indeksów w kolumnach obliczanych.

Krok 2. Wyświetlanie wartości kolumn obliczeniowych

Zanim zaczniemy pracować nad warstwą dostępu do danych, pośmińmy minutę, aby wyświetlić FullContactName wartości. W Eksploratorze serwera kliknij prawym przyciskiem myszy Suppliers nazwę tabeli i wybierz pozycję Nowe zapytanie z menu kontekstowego. Spowoduje to wyświetlenie okna Zapytania z monitem o wybranie tabel do uwzględnienia w zapytaniu. Dodaj tabelę Suppliers i kliknij przycisk Zamknij. Następnie sprawdź CompanyNamekolumny , ContactName, ContactTitlei FullContactName z tabeli Suppliers. Na koniec kliknij ikonę czerwonego wykrzyknika na pasku narzędzi, aby wykonać zapytanie i wyświetlić wyniki.

Jak pokazano na rysunku 2, wyniki obejmują FullContactName, który zawiera listę CompanyNamekolumn , ContactNamei ContactTitle przy użyciu formatu ldquo;ContactName (ContactTitle, CompanyName) .

Nazwa FullContactName używa formatu ContactName (ContactTitle, CompanyName)

Rysunek 2. Użycie formatu ContactName (, CompanyName) (ContactTitlekliknij, aby wyświetlić obraz o FullContactName pełnym rozmiarze)

Krok 3. Dodawanie elementuSuppliersTableAdapterdo warstwy dostępu do danych

Aby pracować z informacjami o dostawcy w naszej aplikacji, musimy najpierw utworzyć tabelę TableAdapter i DataTable w naszym dal. W idealnym przypadku można to zrobić przy użyciu tych samych prostych kroków, które zostały zbadane we wcześniejszych samouczkach. Jednak praca z obliczonymi kolumnami wprowadza kilka zmarszczek, które zasługują na dyskusję.

Jeśli używasz klasy TableAdapter korzystającej z instrukcji ad hoc SQL, możesz po prostu uwzględnić obliczoną kolumnę w głównym zapytaniu tableAdapter za pośrednictwem kreatora konfiguracji tableAdapter. Spowoduje to jednak automatyczne wygenerowanie INSERT instrukcji i UPDATE zawierających obliczoną kolumnę. Jeśli spróbujesz wykonać jedną z tych metod, nie można zmodyfikować komunikatu Nazwakolumny kolumny, SqlException ponieważ jest to obliczona kolumna lub wynik operatora UNION zostanie zgłoszony. Chociaż instrukcję INSERT i UPDATE można ręcznie dostosować za pomocą właściwości i UpdateCommand tableAdapterInsertCommand, te dostosowania zostaną utracone za każdym razem, gdy kreator konfiguracji tableAdapter zostanie ponownie uruchomiony.

Ze względu na kruchość tabel TableAdapters korzystających z instrukcji ad hoc SQL zaleca się używanie procedur składowanych podczas pracy z obliczonymi kolumnami. Jeśli używasz istniejących procedur składowanych, po prostu skonfiguruj metodę TableAdapter zgodnie z opisem w samouczku Using Existing Stored Procedures for the Typed DataSet s TableAdapters (Używanie istniejących procedur składowanych dla typów elementów TableAdapters ). Jeśli jednak kreator TableAdapter utworzy procedury składowane, ważne jest, aby początkowo pominąć wszystkie obliczone kolumny z głównego zapytania. Jeśli w zapytaniu głównym uwzględnisz obliczoną kolumnę, kreator konfiguracji tableAdapter poinformuje Cię po zakończeniu, że nie może utworzyć odpowiednich procedur składowanych. Krótko mówiąc, musimy początkowo skonfigurować tabelę TableAdapter przy użyciu obliczonego zapytania głównego bez kolumny, a następnie ręcznie zaktualizować odpowiednią procedurę składowaną i tabelę TableAdapter w SelectCommand celu uwzględnienia obliczonej kolumny. Takie podejście jest podobne do tego, które zostało użyte w samouczku Aktualizowanie obiektu TableAdapter do korzystania zJOINprogramu s.

Na potrzeby tego samouczka dodajmy nowy element TableAdapter i automatycznie utworzymy dla nas procedury składowane. W związku z tym musimy początkowo pominąć obliczoną kolumnę FullContactName z głównego zapytania.

Rozpocznij od otwarcia zestawu NorthwindWithSprocs danych w folderze ~/App_Code/DAL . Kliknij prawym przyciskiem myszy projektanta, a następnie z menu kontekstowego wybierz polecenie , aby dodać nowy element TableAdapter. Spowoduje to uruchomienie kreatora konfiguracji tableAdapter. Określ bazę danych do wykonywania zapytań względem danych z (NORTHWNDConnectionString z Web.config) i kliknij przycisk Dalej. Ponieważ nie utworzyliśmy jeszcze żadnych procedur składowanych do wykonywania zapytań lub modyfikowania Suppliers tabeli, wybierz opcję Utwórz nowe procedury składowane, aby kreator utworzył je dla nas, a następnie kliknij przycisk Dalej.

Wybierz opcję Utwórz nowe procedury składowane

Rysunek 3. Wybieranie opcji Utwórz nowe procedury składowane (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

W kolejnym kroku zostanie wyświetlony monit o zapytanie główne. Wprowadź następujące zapytanie, które zwraca SupplierIDkolumny , CompanyName, ContactNamei ContactTitle dla każdego dostawcy. Należy pamiętać, że to zapytanie celowo pomija obliczoną kolumnę (FullContactName); zaktualizujemy odpowiednią procedurę składowaną, aby uwzględnić tę kolumnę w kroku 4.

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

Po wprowadzeniu zapytania głównego i kliknięciu przycisku Dalej kreator umożliwia nam nadanie nazwy czterech procedur składowanych, które wygeneruje. Nazwij te procedury Suppliers_Selectskładowane , Suppliers_Insert, Suppliers_Updatei Suppliers_Delete, jak pokazano na rysunku 4.

Dostosowywanie nazw automatycznie generowanych procedur składowanych

Rysunek 4. Dostosowywanie nazw automatycznie generowanych procedur składowanych (kliknij, aby wyświetlić obraz pełnowymiarowy)

Następny krok kreatora umożliwia nam nadanie nazw metodom TableAdapter i określenie wzorców używanych do uzyskiwania dostępu do i aktualizowania danych. Pozostaw zaznaczone wszystkie trzy pola wyboru, ale zmień nazwę metody na GetData GetSuppliers. Kliknij przycisk Zakończ, aby zakończyć kreatora.

Zmień nazwę metody GetData na GetSuppliers

Rysunek 5. Zmiana nazwy metody na GetSuppliers GetData (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Po kliknięciu przycisku Zakończ kreator utworzy cztery procedury składowane i doda tabelę TableAdapter i odpowiadającą jej tabelę DataTable do typu zestawu danych.

Krok 4. Dołączenie obliczonej kolumny w zapytaniu głównym tabeliAdapter

Teraz musimy zaktualizować tabelę TableAdapter i DataTable utworzoną w kroku 3, aby uwzględnić obliczoną kolumnę FullContactName . Obejmuje to dwa kroki:

  1. Aktualizowanie procedury składowanej w Suppliers_Select celu zwrócenia obliczonej FullContactName kolumny i
  2. Aktualizowanie tabeli DataTable w celu uwzględnienia odpowiedniej FullContactName kolumny.

Zacznij od nawigowania do Eksploratora serwera i przechodzenia do szczegółów w folderze Procedury składowane. Otwórz procedurę Suppliers_Select składowaną i zaktualizuj SELECT zapytanie, aby uwzględnić kolumnę obliczeniową FullContactName :

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers

Zapisz zmiany w procedurze składowanej, klikając ikonę Zapisz na pasku narzędzi, naciskając Ctrl+S lub wybierając opcję Zapisz Suppliers_Select z menu Plik.

Następnie wróć do projektanta zestawu danych, kliknij prawym przyciskiem myszy SuppliersTableAdapterpozycję , a następnie wybierz polecenie Konfiguruj z menu kontekstowego. Pamiętaj, że kolumna Suppliers_Select zawiera teraz kolumnę FullContactName w kolekcji Kolumny danych.

Uruchom Kreatora konfiguracji narzędzia TableAdapter, aby zaktualizować kolumny tabeli DataTable

Rysunek 6. Uruchom Kreatora konfiguracji narzędzia TableAdapter, aby zaktualizować kolumny tabeli Danych (kliknij, aby wyświetlić obraz pełnowymiarowy)

Kliknij przycisk Zakończ, aby zakończyć kreatora. Spowoduje to automatyczne dodanie odpowiedniej kolumny do elementu SuppliersDataTable. Kreator TableAdapter jest wystarczająco inteligentny, aby wykryć, że kolumna FullContactName jest kolumną obliczaną i dlatego tylko do odczytu. W związku z tym ustawia właściwość kolumny ReadOnly na truewartość . Aby to sprawdzić, wybierz kolumnę z pola SuppliersDataTable , a następnie przejdź do okno Właściwości (zobacz Rysunek 7). Należy pamiętać, że FullContactName kolumny i DataType MaxLength właściwości są również ustawione odpowiednio.

Kolumna FullContactName jest oznaczona jako tylko do odczytu

Rysunek 7. Kolumna FullContactName jest oznaczona jako tylko do odczytu (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Krok 5. DodawanieGetSupplierBySupplierIDmetody do klasy TableAdapter

Na potrzeby tego samouczka utworzymy stronę ASP.NET wyświetlającą dostawców w siatce z możliwością aktualizacji. W poprzednich samouczkach zaktualizowaliśmy pojedynczy rekord z warstwy logiki biznesowej, pobierając ten konkretny rekord z dal jako silnie typizowanego elementu DataTable, aktualizując jego właściwości, a następnie wysyłając zaktualizowaną tabelę DataTable z powrotem do dal w celu propagowania zmian w bazie danych. Aby wykonać ten pierwszy krok — pobranie rekordu aktualizowanego z poziomu dal — musimy najpierw dodać metodę GetSupplierBySupplierID(supplierID) do dal.

Kliknij prawym przyciskiem myszy element SuppliersTableAdapter w projekcie Zestawu danych i wybierz opcję Dodaj zapytanie z menu kontekstowego. Tak jak w kroku 3, kreator wygeneruje dla nas nową procedurę składowaną, wybierając opcję Utwórz nową procedurę składowaną (wróć do rysunku 3, aby uzyskać zrzut ekranu tego kroku kreatora). Ponieważ ta metoda zwróci rekord z wieloma kolumnami, wskaż, że chcemy użyć zapytania SQL, które jest poleceniem SELECT, które zwraca wiersze, a następnie kliknij przycisk Dalej.

Wybierz pozycję SELECT, która zwraca opcje wierszy

Rysunek 8. Wybierz opcję SELECT, która zwraca wiersze (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

W kolejnym kroku zostanie wyświetlony monit o użycie zapytania dla tej metody. Wprowadź następujące polecenie, które zwraca te same pola danych co zapytanie główne, ale dla określonego dostawcy.

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers
WHERE SupplierID = @SupplierID

Na następnym ekranie zostanie wyświetlony monit o podanie nazwy procedury składowanej, która zostanie wygenerowana automatycznie. Nadaj tej procedurze Suppliers_SelectBySupplierID składowanej nazwę i kliknij przycisk Dalej.

Nazwij Suppliers_SelectBySupplierID procedury składowanej

Rysunek 9. Nadaj procedurze Suppliers_SelectBySupplierID składowanej nazwę (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Na koniec kreator monituje nas o wzorce dostępu do danych i nazwy metod do użycia dla obiektu TableAdapter. Pozostaw zaznaczone oba pola wyboru, ale zmień odpowiednio nazwy metod i GetDataBy na FillBy FillBySupplierID i GetSupplierBySupplierID.

Nazwij metody TableAdapter FillBySupplierID i GetSupplierBySupplierID

Rysunek 10. Nadaj metodom FillBySupplierID TableAdapter nazwę i GetSupplierBySupplierID (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Kliknij przycisk Zakończ, aby zakończyć kreatora.

Krok 6. Tworzenie warstwy logiki biznesowej

Przed utworzeniem strony ASP.NET używającej obliczonej kolumny utworzonej w kroku 1 należy najpierw dodać odpowiednie metody w usłudze BLL. Nasza strona ASP.NET, którą utworzymy w kroku 7, umożliwi użytkownikom wyświetlanie i edytowanie dostawców. W związku z tym potrzebujemy naszej BLL, aby zapewnić co najmniej metodę, aby wszyscy dostawcy i inny dostawca zaktualizowali określonego dostawcę.

Utwórz nowy plik klasy o nazwie SuppliersBLLWithSprocs w folderze ~/App_Code/BLL i dodaj następujący kod:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class SuppliersBLLWithSprocs
{
    private SuppliersTableAdapter _suppliersAdapter = null;
    protected SuppliersTableAdapter Adapter
    {
        get
        {
            if (_suppliersAdapter == null)
                _suppliersAdapter = new SuppliersTableAdapter();
            return _suppliersAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.SuppliersDataTable GetSuppliers()
    {
        return Adapter.GetSuppliers();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Update, true)]
    public bool UpdateSupplier(string companyName, string contactName, 
        string contactTitle, int supplierID)
    {
        NorthwindWithSprocs.SuppliersDataTable suppliers = 
            Adapter.GetSupplierBySupplierID(supplierID);
        if (suppliers.Count == 0)
            // no matching record found, return false
            return false;
        NorthwindWithSprocs.SuppliersRow supplier = suppliers[0];
        supplier.CompanyName = companyName;
        if (contactName == null) 
            supplier.SetContactNameNull(); 
        else 
            supplier.ContactName = contactName;
        if (contactTitle == null) 
            supplier.SetContactTitleNull(); 
        else 
            supplier.ContactTitle = contactTitle;
        // Update the product record
        int rowsAffected = Adapter.Update(supplier);
        // Return true if precisely one row was updated, otherwise false
        return rowsAffected == 1;
    }
}

Podobnie jak inne klasy BLL, ma Adapter protected właściwość, SuppliersBLLWithSprocs która zwraca wystąpienie SuppliersTableAdapter klasy wraz z dwiema public metodami: GetSuppliers i UpdateSupplier. Metoda GetSuppliers wywołuje metodę i zwraca SuppliersDataTable wartość zwróconą przez odpowiednią GetSupplier metodę w warstwie dostępu do danych. Metoda UpdateSupplier pobiera informacje o konkretnym dostawcy aktualizowanym za pośrednictwem wywołania metody DAL.GetSupplierBySupplierID(supplierID) Następnie aktualizuje CategoryNamewłaściwości , ContactNamei ContactTitle zatwierdza te zmiany w bazie danych, wywołując metodę warstwy Update dostępu do danych, przekazując zmodyfikowany SuppliersRow obiekt.

Uwaga

Z wyjątkiem wartości SupplierID i CompanyName, wszystkie kolumny w tabeli Dostawcy zezwalają na NULL wartości. W związku z tym, jeśli przekazane lub parametry są null potrzebne, musimy ustawić odpowiednie ContactName właściwości i ContactTitle na NULL wartość bazy danych przy użyciu SetContactNameNull metod iSetContactTitleNull, contactTitle contactName odpowiednio.

Krok 7. Praca z obliczoną kolumną z warstwy prezentacji

Po dodaniu kolumny obliczeniowej Suppliers do tabeli oraz odpowiednio zaktualizowaniu dal i BLL możemy utworzyć stronę ASP.NET, która współpracuje z obliczoną FullContactName kolumną. Zacznij od otwarcia ComputedColumns.aspx strony w folderze AdvancedDAL i przeciągnięcia kontrolki GridView z przybornika do projektanta. Ustaw właściwość GridView ID na Suppliers i, z tagu inteligentnego, powiąż ją z nowym obiektem ObjectDataSource o nazwie SuppliersDataSource. Skonfiguruj obiekt ObjectDataSource, aby użyć SuppliersBLLWithSprocs klasy dodanej z powrotem w kroku 6, a następnie kliknij przycisk Dalej.

Konfigurowanie obiektu ObjectDataSource do używania klasy SuppliersBLLWithSprocs

Rysunek 11. Konfigurowanie obiektu ObjectDataSource do używania SuppliersBLLWithSprocs klasy (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

W klasie zdefiniowano SuppliersBLLWithSprocs tylko dwie metody: GetSuppliers i UpdateSupplier. Upewnij się, że te dwie metody są określone odpowiednio na kartach SELECT i UPDATE, a następnie kliknij przycisk Zakończ, aby ukończyć konfigurację obiektu ObjectDataSource.

Po zakończeniu pracy Kreatora konfiguracji źródła danych program Visual Studio doda pole BoundField dla każdego zwróconego pola danych. Usuń pole SupplierID BoundField i zmień HeaderText odpowiednio właściwości CompanyNamepól , ContactName, ContactTitlei FullContactName BoundFields na Company, Contact Name, Title i Full Contact Name. W tagu inteligentnym zaznacz pole wyboru Włącz edytowanie, aby włączyć wbudowane możliwości edytowania kontrolki GridView.

Oprócz dodawania elementów BoundFields do kontrolki GridView ukończenie Kreatora źródła danych powoduje również, że program Visual Studio ustawi właściwość ObjectDataSource na OldValuesParameterFormatString original_{0}. Przywróć to ustawienie z powrotem na wartość domyślną . {0}

Po wprowadzeniu tych zmian w elementy GridView i ObjectDataSource ich deklaratywne znaczniki powinny wyglądać podobnie do następujących:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="CompanyName" 
            HeaderText="Company" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="ContactName" 
            HeaderText="Contact Name" 
            SortExpression="ContactName" />
        <asp:BoundField DataField="ContactTitle" 
            HeaderText="Title" 
            SortExpression="ContactTitle" />
        <asp:BoundField DataField="FullContactName" 
            HeaderText="Full Contact Name"
            SortExpression="FullContactName" 
            ReadOnly="True" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLLWithSprocs" 
        UpdateMethod="UpdateSupplier">
    <UpdateParameters>
        <asp:Parameter Name="companyName" Type="String" />
        <asp:Parameter Name="contactName" Type="String" />
        <asp:Parameter Name="contactTitle" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Następnie odwiedź tę stronę za pośrednictwem przeglądarki. Jak pokazano na rysunku 12, każdy dostawca jest wymieniony w siatce zawierającej FullContactName kolumnę, której wartość jest po prostu łączeniem pozostałych trzech kolumn sformatowanych jako ContactName (ContactTitle, CompanyName) .

Każdy dostawca jest wymieniony w siatce

Rysunek 12. Każdy dostawca znajduje się na liście w siatce (kliknij, aby wyświetlić obraz pełnowymiarowy)

Kliknięcie przycisku Edytuj dla określonego dostawcy powoduje wycofanie i wyświetlenie tego wiersza w interfejsie edycji (zobacz Rysunek 13). Pierwsze trzy kolumny są renderowane w domyślnym interfejsie edycji — kontrolka TextBox, której Text właściwość jest ustawiona na wartość pola danych. Kolumna FullContactName pozostaje jednak tekstem. Po dodaniu elementów BoundFields do kontrolki GridView po zakończeniu pracy kreatora konfiguracji źródła danych właściwość BoundField ReadOnly została ustawiona na true , FullContactName ponieważ odpowiadająca FullContactName kolumna w SuppliersDataTable obiekcie ma ustawioną ReadOnly właściwość na truewartość . Jak wspomniano w kroku 4, właściwość s ReadOnly została ustawiona natrue, FullContactName ponieważ tableAdapter wykrył, że kolumna była kolumną obliczoną.

Kolumna FullContactName nie jest edytowalna

Rysunek 13. Kolumna FullContactName nie jest edytowalna (kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Przejdź dalej i zaktualizuj wartość co najmniej jednej edytowalnej kolumny i kliknij przycisk Aktualizuj. Zwróć uwagę, FullContactName jak wartość s jest automatycznie aktualizowana w celu odzwierciedlenia zmiany.

Uwaga

Obiekt GridView obecnie używa pól BoundFields dla pól edytowalnych, co powoduje domyślny interfejs edycji. CompanyName Ponieważ pole jest wymagane, należy przekonwertować je na pole szablonu, które zawiera element RequiredFieldValidator. Zostawię to jako ćwiczenie dla zainteresowanego czytelnika. Zapoznaj się z samouczkiem Dodawanie kontrolek walidacji do samouczka Edytowanie i wstawianie interfejsów , aby uzyskać instrukcje krok po kroku dotyczące konwertowania pola BoundField na pole szablonu i dodawania kontrolek walidacji.

Podsumowanie

Podczas definiowania schematu dla tabeli program Microsoft SQL Server umożliwia dołączenie obliczonych kolumn. Są to kolumny, których wartości są obliczane na podstawie wyrażenia, które zwykle odwołuje się do wartości z innych kolumn w tym samym rekordzie. Ponieważ wartości kolumn obliczeniowych są oparte na wyrażeniu, są tylko do odczytu i nie można przypisać wartości w instrukcji INSERT or UPDATE . Spowoduje to wprowadzenie wyzwań podczas używania obliczonej kolumny w głównym zapytaniu tableAdapter, które próbuje automatycznie wygenerować odpowiednie INSERTinstrukcje , UPDATEi DELETE .

W tym samouczku omówiliśmy techniki obejścia wyzwań stwarzanych przez obliczone kolumny. W szczególności użyliśmy procedur składowanych w naszej tabeli TableAdapter, aby przezwyciężyć kruchość związaną z metodami TableAdapters, które używają instrukcji AD hoc JĘZYKA SQL. Jeśli kreator TableAdapter tworzy nowe procedury składowane, ważne jest, aby główne zapytanie początkowo pomijało wszystkie obliczone kolumny, ponieważ ich obecność uniemożliwia generowanie procedur składowanych modyfikacji danych. Po początkowym skonfigurowaniu obiektu TableAdapter można ponownie skonfigurować procedurę SelectCommand składowaną w celu uwzględnienia dowolnych obliczonych kolumn.

Szczęśliwe programowanie!

Informacje o autorze

Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w 24 godzinach. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com. lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.

Specjalne podziękowania

Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Recenzenci w tym samouczku to Hilton Geisenow i Teresa Murphy. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresem mitchell@4GuysFromRolla.com.