Udostępnij za pośrednictwem


Wskazówki: uzyskiwanie dostępu do bazy danych SQL za pomocą dostawców typów (F#)

W tym przewodniku wyjaśniono, w jaki sposób używać dostawcy typu SqlDataConnection (LINQ to SQL), który jest dostępny w języku F# 3.0 do generowania typów dla danych w bazie danych SQL, gdy połączenie z bazą danych jest aktywne.Jeśli połączenie z bazą danych nie jest aktywne, ale posiadasz plik schematu LINQ to SQL (plik DBML), zobacz Wskazówki: generowanie typów F# za pomocą pliku DBML (F#).

Ten przewodnik pokazuje następujące zadania:Zadania te muszą zostać wykonane w podanej kolejności, aby ukończenie przewodnika powiodło się:

  • Przygotowanie testowej bazy danych

  • Tworzenie projektu

  • Konfigurowanie dostawcy typu

  • Wykonywanie zapytania na danych

  • Praca z polami dopuszczającymi wartość null

  • Wywołanie procedury przechowywanej

  • Aktualizowanie bazy danych

  • Wykonywanie kodu języka Transact-SQL.

  • Używanie pełnego kontekstu danych

  • Usuwanie danych

  • Tworzenie testowej bazy danych

Przygotowanie testowej bazy danych

Na serwerze, na którym jest uruchomiony program SQL Server, utwórz bazę danych do celów testowych.W tym celu możesz użyć skryptu tworzącego bazę danych, podanego u dołu tej strony, w sekcji Tworzenie testowej bazy danych.

Aby przygotować testową bazę danych

  • Aby uruchomić Tworzenie testowej bazy danych, otwórz menu Widok, a następnie wybierz Eksplorator obiektów programu SQL Server lub użyj klawiszy Ctrl+\, Ctrl+S.W oknie Eksplorator obiektów programu SQL Server, otwórz menu skrótów odpowiedniego wystąpienia, wybierz Nowe zapytanie, skopiuj skrypt z dołu tej strony, a następnie wklej skrypt do edytora.Aby uruchomić skrypt SQL, wybierz ikonę paska narzędzi z trójkątnym symbolem lub użyj klawiszy Ctrl+Q.Aby uzyskać więcej informacji o Eksploratorze obiektów programu SQL Server, zobacz Rozwój połączonej bazy danych.

Tworzenie projektu

Następnie, utworzysz projekt aplikacji F#.

Aby utworzyć i skonfigurować projekt

  1. Utwórz nowy projekt aplikacji F#.

  2. Dodaj odwołania do .FSharp.Data.TypeProviders, jak również do System.Data i System.Data.Linq.

  3. Otwórz odpowiednie przestrzenie nazw, dodając następujące linie kodu na początku pliku Program.fs z kodem F#.

    open System
    open System.Data
    open System.Data.Linq
    open Microsoft.FSharp.Data.TypeProviders
    open Microsoft.FSharp.Linq
    
  4. Podobnie jak w przypadku większości programów F#, możesz wykonać kod z tego przewodnika jako skompilowany program lub uruchomić go interakcyjnie jako skrypt.Jeśli wolisz używać skryptów, otwórz menu skrótów dla węzła projektu, wybierz Dodaj nowy element, dodaj plik skryptu F# i dodaj kod skryptu z każdego kroku.Musisz dodać następujące linie na początku pliku, aby załadować odwołania zestawu.

    #r "System.Data.dll"
    #r "FSharp.Data.TypeProviders.dll"
    #r "System.Data.Linq.dll"
    

    Następnie zaznacz każdy blok kodu podczas dodawania go i naciśnij klawisze Alt+Enter, aby uruchomić go w programie F# Interactive.

Konfigurowanie dostawcy typu

W tym kroku, utworzysz dostawcę typu dla schematu bazy danych.

Aby skonfigurować dostawcę typu z bezpośredniego połączenia z bazą danych

  • Istnieją dwie krytyczne linie kodu, które są wymagane, aby utworzyć typy, których można użyć do zapytania bazy danych SQL przy użyciu dostawcy typu.Najpierw, tworzysz wystąpienie dostawcy typu.Aby to zrobić, utwórz coś, co wygląda jak skrót typu dla SqlDataConnection ze statycznym parametrem generycznym.SqlDataConnection jest dostawcą typu SQL i nie należy go mylić z typem SqlConnection, który jest wykorzystywany w programowaniu z użyciem ADO.NET.Jeśli masz bazę danych, z którą chcesz się połączyć i posiadasz parametry połączenia, użyj następującego kodu do wywołania dostawcy typu.Podstaw swoje własne parametry połączenia zamiast podanych parametrów przykładowych.Na przykład, jeśli serwer to MYSERVER, wystąpienie bazy danych to INSTANCE, nazwa bazy danych to MyDatabase i chcesz używać uwierzytelniania systemu Windows, aby uzyskać dostęp do bazy danych, to parametry połączenia będą takie, jak w poniższym kodzie przykładowym.

    type dbSchema = SqlDataConnection<"Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;">
    let db = dbSchema.GetDataContext()
    
    // Enable the logging of database activity to the console.
    db.DataContext.Log <- System.Console.Out
    

    Teraz posiadasz typ dbSchema, który jest typem nadrzędnym zawierającym wszystkie wygenerowane typy reprezentowane w tabelach bazy danych.Posiadasz również obiekt db, który ma wszystkie tabele bazy danych jako swoje elementy członkowskie.Nazwy tabel są właściwościami, a typ tych właściwości jest generowany przez kompilator F#.Same typy są wyświetlane jako typy zagnieżdżone typów pod dbSchema.ServiceTypes.Z tego powodu, wszelkie dane pobierane do wierszy tabel są wystąpieniem odpowiedniego typu, który został wygenerowany dla tabeli.Nazwa typu to ServiceTypes.Table1.

    Aby zapoznać się ze sposobem, w jaki język F# interpretuje zapytania SQL, przyjrzyj się linii kodu, w której ustawiana jest właściwość Log kontekstu danych.

    Aby zbadać typy utworzone przez dostawcę typu, dodaj następujący kod.

    let table1 = db.Table1
    

    Przesuń kursor nad table1, aby zobaczyć jej typ.Jej typ to System.Data.Linq.Table<dbSchema.ServiceTypes.Table1>, a argument generyczny zakłada, że typ każdego wiersza jest wygenerowanym typem dbSchema.ServiceTypes.Table1.Kompilator tworzy podobny typ dla każdej tabeli w bazie danych.

Wykonywanie zapytania na danych

W tym kroku napiszesz zapytanie za pomocą wyrażeń zapytania języka F#.

Aby utworzyć zapytanie do danych

  1. Teraz utwórz zapytanie do tabeli bazy danych.Dodaj następujący kod.

    let query1 =
            query {
                for row in db.Table1 do
                select row
            }
    query1 |> Seq.iter (fun row -> printfn "%s %d" row.Name row.TestData1)
    

    Wygląd wyrazu query wskazuje, że jest to wyrażenie zapytania, rodzaj wyrażenia obliczeń, które generuje kolekcję wyników podobnych do typowego zapytania bazy danych.Po przesunięciu kursora nad zapytanie, zobaczysz, że jest to wystąpienie Linq.QueryBuilder — Klasa (F#), typu, który definiuje wyrażenie obliczeń kwerendy.Po przesunięciu kursora nad query1, zobaczysz, że jest to wystąpienie IQueryable.Jak sugeruje nazwa, IQueryable reprezentuje dane, do których można wykonać zapytanie, a nie wynik działania zapytania.Zapytanie jest obliczane leniwie, co oznacza, że zapytanie do bazy danych jest wykonywane dopiero podczas obliczania zapytania.Ostatnia linia przekazuje zapytanie za pomocą Seq.iter.Zapytania są wyliczalne i mogą być iterowane jak sekwencje.Aby uzyskać więcej informacji, zobacz Wyrażenia kwerend (F#).

  2. Teraz dodaj operator zapytania do zapytania.Dostępnych jest wiele operatorów zapytania, które mogą zostać wykorzystane do skonstruowania bardziej złożonych zapytań.Ten przykład pokazuje również, że można wyeliminować zmienną zapytania i użyć zamiast niej operatora potoku.

    query {
            for row in db.Table1 do
            where (row.TestData1 > 2)
            select row
          }
    |> Seq.iter (fun row -> printfn "%d %s" row.TestData1 row.Name)
    
  3. Dodaj bardziej złożone zapytanie ze sprzężeniem dwóch tabel.

    query {
            for row1 in db.Table1 do
            join row2 in db.Table2 on (row1.Id = row2.Id)
            select (row1, row2)
    }
    |> Seq.iteri (fun index (row1, row2) ->
         if (index = 0) then printfn "Table1.Id TestData1 TestData2 Name Table2.Id TestData1 TestData2 Name"
         printfn "%d %d %f %s %d %d %f %s" row1.Id row1.TestData1 row1.TestData2 row1.Name
             row2.Id (row2.TestData1.GetValueOrDefault()) (row2.TestData2.GetValueOrDefault()) row2.Name)
    
  4. W kodzie rzeczywistym, parametrami w zapytaniu są zwykle wartości lub zmienne, a nie stałe czasu kompilacji.Dodaj następujący kod, który otacza zapytanie w funkcji, która przyjmuje parametr, a następnie wywołuje funkcję z wartością 10.

    let findData param =
        query {
            for row in db.Table1 do
            where (row.TestData1 = param)
            select row
            }
    findData 10 |> Seq.iter (fun row -> printfn "Found row: %d %d %f %s" row.Id row.TestData1 row.TestData2 row.Name)
    

Praca z polami dopuszczającymi wartość null

W bazach danych, pola często zezwalają na wartości null.W systemie typów .NET, nie można używać zwykłych typów danych liczbowych dla danych, które zezwalają na wartość null, ponieważ typy te nie posiadają wartości null jako możliwej wartości.Z tego powodu, wartości te są reprezentowane przez wystąpienia typu Nullable.Zamiast uzyskać dostęp do wartości takiego pola bezpośrednio, za pomocą jego nazwy, należy wykonać kilka dodatkowych kroków.Możesz użyć właściwości Value, aby uzyskać dostęp do podstawowej wartości typu dopuszczającego wartość null.Właściwość Value zgłasza wyjątek, jeśli obiekt ma wartość null zamiast mieć inną wartość.Możesz użyć metody HasValue zwracającej wartość logiczną, aby ustalić, czy wartość istnieje lub użyć GetValueOrDefault, aby zapewnić, że posiadasz bieżącą wartość we wszystkich przypadkach.Jeśli użyjesz metody GetValueOrDefault, a w bazie danych będzie wartość null, to zostanie ona zastąpiona wartością taką jak ciąg pusty dla typów znakowych, 0 dla typów całkowitych lub 0.0 dla typów zmiennoprzecinkowych.

Jeśli trzeba wykonać testy równości lub porównania na wartościach null w klauzuli where zapytania, można użyć operatorów dopuszczających wartość null, które można znaleźć w Linq.NullableOperators — Moduł (F#).Są one jak zwykłe operatory porównania =, >, <=, itd., z tą różnicą, że po stronie operatora, która dopuszcza wartość null, wyświetlany jest znak zapytania.Na przykład, operator >? jest operatorem większe-niż, dopuszczającym wartość null po prawej stronie.Sposób działania tych operatorów jest następujący: jeśli po obu stronach wyrażenia jest wartość null, to wyrażenie jest obliczane jako false.W klauzuli where, oznacza to zazwyczaj, że wiersze zawierające pola null nie zostaną wybrane ani zwrócone w wyniku zapytania.

Aby pracować z polami dopuszczającymi wartość null

  • Poniższy kod przedstawia pracę z wartościami null; załóżmy, że TestData1 jest polem wartości całkowitych, które dopuszcza wartość null.

    query {
            for row in db.Table2 do
            where (row.TestData1.HasValue && row.TestData1.Value > 2)
            select row
          }
    |> Seq.iter (fun row -> printfn "%d %s" row.TestData1.Value row.Name)
    
    query {
            for row in db.Table2 do
            // Use a nullable operator ?>
            where (row.TestData1 ?> 2)
            select row
          }
    |> Seq.iter (fun row -> printfn "%d %s" (row.TestData1.GetValueOrDefault()) row.Name)
    

Wywołanie procedury przechowywanej

Wszelkie procedury przechowywanych w bazie danych mogą zostać wywołane z F#.Musisz ustawić parametr statyczny StoredProcedures na true w wystąpieniu dostawcy typu.Dostawca typu SqlDataConnection zawiera kilka metod statycznych, które służą do konfigurowania generowanych typów.Aby uzyskać ich pełny opis, zobacz SqlDataConnection — Typ dostawcy (F#).Metoda typu kontekstu danych jest generowana dla każdej procedury przechowywanej.

Aby wywołać procedurę przechowywaną

  • Jeśli procedura przechowywana przyjmuje parametry, które dopuszczają wartość null, musisz przekazać odpowiednie wartości Nullable.Wartość zwracana przez metodę procedury przechowywanej, która zwraca wartość skalarną lub tabelę to ISingleResult, który zawiera właściwości umożliwiające dostęp do zwróconych danych.Typ argumentu ISingleResult zależy od określonej procedury i jest również jednym z typów, które generuje dostawca typu.Dla procedury przechowywanej o nazwie Procedure1, typem jest Procedure1Result.Typ Procedure1Result zawiera nazwy kolumn w zwracanej tabeli lub, w przypadku procedury przechowywanej, która zwraca wartość skalarną, reprezentuje wartość zwracaną.

    Następujący kod zakłada istnienie w bazie danych procedury Procedure1, która jako parametry przyjmuje dwie liczby całkowite dopuszczające wartość null, uruchamia zapytanie, które zwraca kolumnę o nazwie TestData1 i zwraca liczbę całkowitą.

    
    type schema = SqlDataConnection<"Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;",
                                    StoredProcedures = true>
    
    let testdb = schema.GetDataContext()
    
    let nullable value = new System.Nullable<_>(value)
    
    let callProcedure1 a b =
        let results = testdb.Procedure1(nullable a, nullable b)
        for result in results do
            printfn "%d" (result.TestData1.GetValueOrDefault())
        results.ReturnValue :?> int
    
    printfn "Return Value: %d" (callProcedure1 10 20)
    

Aktualizowanie bazy danych

Typ LINQ DataContext zawiera metody, które ułatwiają przeprowadzanie transakcyjnych aktualizacji bazy danych w sposób w pełni typizowany za pomocą wygenerowanych typów.

Aby zaktualizować bazę danych

  1. W poniższym kodzie, do bazy danych dodawane jest kilka wierszy.Jeśli chcesz dodać pojedynczy wiersz, możesz użyć InsertOnSubmit, aby określić nowy wiersz do dodania.Jeśli wstawisz wiele wierszy, umieść je w kolekcji i wywołaj metodę InsertAllOnSubmit``1.Podczas wywołania dowolnej z tych metod, baza danych nie jest zmieniana natychmiast.Musisz wywołać metodę SubmitChanges, aby faktycznie zatwierdzić zmiany.Domyślnie, wszystko, co zostanie wykonane przed wywołaniem metody SubmitChanges, jest niejawnie częścią tej samej transakcji.

    let newRecord = new dbSchema.ServiceTypes.Table1(Id = 100,
                                                     TestData1 = 35, 
                                                     TestData2 = 2.0,
                                                     Name = "Testing123")
    let newValues =
        [ for i in [1 .. 10] ->
              new dbSchema.ServiceTypes.Table3(Id = 700 + i,
                                               Name = "Testing" + i.ToString(),
                                               Data = i) ]
    // Insert the new data into the database.
    db.Table1.InsertOnSubmit(newRecord)
    db.Table3.InsertAllOnSubmit(newValues)
    try
        db.DataContext.SubmitChanges()
        printfn "Successfully inserted new rows."
    with
       | exn -> printfn "Exception:\n%s" exn.Message
    
  2. Teraz oczyścić wiersze przez wywołanie operacji usuwania.

    // Now delete what was added.
    db.Table1.DeleteOnSubmit(newRecord)
    db.Table3.DeleteAllOnSubmit(newValues)
    try
        db.DataContext.SubmitChanges()
        printfn "Successfully deleted all pending rows."
    with
       | exn -> printfn "Exception:\n%s" exn.Message
    

Wykonywanie kodu języka Transact-SQL.

Możesz również określić język Transact-SQL bezpośrednio, za pomocą metody ExecuteCommand z klasy DataContext.

Aby wykonać niestandardowe polecenia SQL

  • Poniższy kod przedstawia, w jaki sposób wysyłać polecenia SQL, aby wstawić rekord do tabeli oraz jak usunąć rekord z tabeli.

    try
       db.DataContext.ExecuteCommand("INSERT INTO Table3 (Id, Name, Data) VALUES (102, 'Testing', 55)") |> ignore
    with
       | exn -> printfn "Exception:\n%s" exn.Message
    try //AND Name = 'Testing' AND Data = 55
       db.DataContext.ExecuteCommand("DELETE FROM Table3 WHERE Id = 102 ") |> ignore
    with
       | exn -> printfn "Exception:\n%s" exn.Message
    

Używanie pełnego kontekstu danych

W poprzednich przykładach, metoda GetDataContext była używana do pobrania tego, co jest nazywane uproszczonym kontekstem danych dla schematu bazy danych.Uproszczony kontekst danych jest łatwiejszy w użyciu przy konstruowaniu zapytań, ponieważ nie ma on tak wielu dostępnych elementów członkowskich.Z tego powodu, podczas przeglądania właściwości w technologii IntelliSense, możesz skupić się na strukturze bazy danych, takiej jak tabele i procedury przechowywane.Jednakże, to co możesz zrobić za pomocą uproszczonego kontekstu danych jest ograniczone.Pełny kontekst danych, który zapewnia możliwość wykonywania pozostałych akcjijest również dostępny. Jest on zlokalizowany w ServiceTypes i ma nazwę parametru statycznego DataContext, jeśli ją dostarczysz.Jeśli jej nie dostarczysz, nazwa typu kontekstu danych zostanie wygenerowana dla ciebie przez SqlMetal.exe na podstawie innych danych.Pełny kontekst danych dziedziczy po DataContext i uwidacznia elementy członkowskie jego klas podstawowych, w tym odwołania do typów danych ADO.NET, takie jak obiekt Connection, metody, takie jak ExecuteCommand oraz ExecuteQuery``1, których można użyć do pisania zapytań w języku SQL, jak również środki do pracy z transakcjami jawnie.

Aby używać pełnego kontekstu danych

  • W poniższym kodzie pokazano pobieranie obiektu pełnego kontekstu danych i używanie go do wykonywania poleceń bezpośrednio w bazie danych.W tym przypadku, dwa polecenia są wykonywane jako część tej samej transakcji.

    let dbConnection = testdb.Connection
    let fullContext = new dbSchema.ServiceTypes.MyDatabase(dbConnection)
    dbConnection.Open()
    let transaction = dbConnection.BeginTransaction()
    fullContext.Transaction <- transaction
    try
        let result1 = fullContext.ExecuteCommand("INSERT INTO Table3 (Id, Name, Data) VALUES (102, 'A', 55)")
        printfn "ExecuteCommand Result: %d" result1
        let result2 = fullContext.ExecuteCommand("INSERT INTO Table3 (Id, Name, Data) VALUES (103, 'B', -2)")
        printfn "ExecuteCommand Result: %d" result2
        if (result1 <> 1 || result2 <> 1) then
            transaction.Rollback()
            printfn "Rolled back creation of two new rows."
        else
            transaction.Commit()
            printfn "Successfully committed two new rows."
    with
        | exn -> transaction.Rollback()
                 printfn "Rolled back creation of two new rows due to exception:\n%s" exn.Message
    
    dbConnection.Close()
    

Usuwanie danych

W tym kroku pokazano, w jaki sposób usunąć wiersze z tabeli danych.

Aby usunąć wiersze z bazy danych

  • Wyczyść wszelkie dodane wiersze, poprzez napisanie funkcji, która usuwa wiersze z określonej tabeli, wystąpienia klasy Table.Następnie napisz zapytanie, aby znaleźć wszystkie wiersze, które chcesz usunąć i przekaż potok wyników zapytania do funkcji deleteRows.Kod ten korzysta z możliwości dostarczenia tylko części argumentów do funkcji.

    let deleteRowsFrom (table:Table<_>) rows =
        table.DeleteAllOnSubmit(rows)
    
    query {
        for rows in db.Table3 do
        where (rows.Id > 10)
        select rows
        }
    |> deleteRowsFrom db.Table3
    
    db.DataContext.SubmitChanges()
    printfn "Successfully deleted rows with Id greater than 10 in Table3."
    

Tworzenie testowej bazy danych

W tej sekcji pokazano, w jaki sposób skonfigurować testową bazę danych, wykorzystywaną w tym przewodniku.

Zauważ, że jeśli w jakiś sposób zmienisz bazę danych, musisz zresetować dostawcę typu.Aby zresetować dostawcę typu, przekompiluj lub oczyść projekt, który zawiera dostawcę typu.

Aby utworzyć testową bazę danych

  1. W Eksploratorze serwera, otwórz menu skrótów węzła Połączenia danych i wybierz polecenie Dodaj połączenie.Pojawi się okno dialogowe Dodaj połączenie.

  2. W polu Nazwa serwera, określ nazwę wystąpienia programu SQL Server, do którego masz dostęp administracyjny lub, jeśli nie masz dostępu do serwera, określ (localdb\v11.0).SQL Express LocalDB dostarcza lekki serwer bazy danych do rozwoju i testowania na twoim komputerze.Nowy węzeł zostanie utworzony w Eksploratorze serwera pod Połączenia danych.Aby uzyskać więcej informacji o LocalDB, zobacz Wskazówki: tworzenie lokalnego pliku bazy danych w programie Visual Studio.

  3. Otwórz menu skrótów nowego węzła połączenia i wybierz Nowe zapytanie.

  4. Skopiuj poniższy skrypt SQL, wklej go do edytora zapytania, a następnie kliknij przycisk Wykonaj na pasku narzędzi lub użyj klawiszy Ctrl+Shift+E.

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    USE [master];
    GO
    
    IF EXISTS (SELECT * FROM sys.databases WHERE name = 'MyDatabase')
                    DROP DATABASE MyDatabase;
    GO
    
    -- Create the MyDatabase database.
    CREATE DATABASE MyDatabase;
    GO
    
    -- Specify a simple recovery model 
    -- to keep the log growth to a minimum.
    ALTER DATABASE MyDatabase 
                    SET RECOVERY SIMPLE;
    GO
    
    USE MyDatabase;
    GO
    
    -- Create the Table1 table.
    CREATE TABLE [dbo].[Table1] (
        [Id]        INT        NOT NULL,
        [TestData1] INT        NOT NULL,
        [TestData2] FLOAT (53) NOT NULL,
        [Name]      NTEXT      NOT NULL,
        PRIMARY KEY CLUSTERED ([Id] ASC)
    );
    
    --Create Table2.
    CREATE TABLE [dbo].[Table2] (
        [Id]        INT        NOT NULL,
        [TestData1] INT        NULL,
        [TestData2] FLOAT (53) NULL,
        [Name]      NTEXT      NOT NULL,
        PRIMARY KEY CLUSTERED ([Id] ASC)
    );
    
    
    --     Create Table3.
    CREATE TABLE [dbo].[Table3] (
        [Id]   INT           NOT NULL,
        [Name] NVARCHAR (50) NOT NULL,
        [Data] INT           NOT NULL,
        PRIMARY KEY CLUSTERED ([Id] ASC)
    );
    GO
    
    CREATE PROCEDURE [dbo].[Procedure1]
           @param1 int = 0,
           @param2 int
    AS
           SELECT TestData1 FROM Table1
    RETURN 0
    GO
    
    -- Insert data into the Table1 table.
    USE MyDatabase
    
    INSERT INTO Table1 (Id, TestData1, TestData2, Name)
    VALUES(1, 10, 5.5, 'Testing1');
    INSERT INTO Table1 (Id, TestData1, TestData2, Name)
    VALUES(2, 20, -1.2, 'Testing2');
    
    --Insert data into the Table2 table.
    INSERT INTO Table2 (Id, TestData1, TestData2, Name)
    VALUES(1, 10, 5.5, 'Testing1');
    INSERT INTO Table2 (Id, TestData1, TestData2, Name)
    VALUES(2, 20, -1.2, 'Testing2');
    INSERT INTO Table2 (Id, TestData1, TestData2, Name)
    VALUES(3, NULL, NULL, 'Testing3');
    
    INSERT INTO Table3 (Id, Name, Data)
    VALUES (1, 'Testing1', 10);
    INSERT INTO Table3 (Id, Name, Data)
    VALUES (2, 'Testing2', 100);
    

Zobacz też

Zadania

Wskazówki: generowanie typów F# za pomocą pliku DBML (F#)

Informacje

SqlDataConnection — Typ dostawcy (F#)

Wyrażenia kwerend (F#)

SqlMetal.exe (Narzędzie generowania kodu)

Inne zasoby

Dostawcy typów

LINQ to SQL [LINQ to SQL]