diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json index a592621bf2dd8..b055e503d1c3d 100644 --- a/.openpublishing.redirection.json +++ b/.openpublishing.redirection.json @@ -1125,6 +1125,34 @@ { "source_path": "docs/csharp/programming-guide/strings/how-to-compare-strings.md", "redirect_url": "/dotnet/csharp/how-to/compare-strings" + }, + { + "source_path": "docs/csharp/classes.md", + "redirect_url": "/dotnet/csharp/programming-guide/classes-and-structs/classes" + }, + { + "source_path": "docs/fsharp/tutorials/type-providers/accessing-a-sql-database-entities.md", + "redirect_url": "/dotnet/fsharp/tutorials/type-providers/index" + }, + { + "source_path": "docs/fsharp/tutorials/type-providers/accessing-a-sql-database.md", + "redirect_url": "/dotnet/fsharp/tutorials/type-providers/index" + }, + { + "source_path": "docs/fsharp/tutorials/type-providers/accessing-a-web-service.md", + "redirect_url": "/dotnet/fsharp/tutorials/type-providers/index" + }, + { + "source_path": "docs/fsharp/tutorials/type-providers/accessing-an-odata-service.md", + "redirect_url": "/dotnet/fsharp/tutorials/type-providers/index" + }, + { + "source_path": "docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-dbml.md", + "redirect_url": "/dotnet/fsharp/tutorials/type-providers/index" + }, + { + "source_path": "docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-edmx.md", + "redirect_url": "/dotnet/fsharp/tutorials/type-providers/index" } ] } diff --git a/docs/csharp/classes.md b/docs/csharp/classes.md deleted file mode 100644 index 259ab900984b7..0000000000000 --- a/docs/csharp/classes.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Classes - C# Guide -description: Learn about the class types and how you create them -keywords: .NET, .NET Core, C# -author: BillWagner -ms.author: wiwagn -ms.date: 10/10/2016 -ms.topic: article -ms.prod: .net -ms.technology: devlang-csharp -ms.devlang: csharp -ms.assetid: 95c686ba-ae4f-440e-8e94-0dbd6e04d11f ---- - -# Classes -A *class* is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared as static, client code can use it by creating *objects* or *instances* which are assigned to a variable. The variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as [static](language-reference/keywords/static.md), then only one copy exists in memory and client code can only access it through the class itself, not an *instance variable*. For more information, see [Static classes and static class members](programming-guide/classes-and-structs/static-classes-and-static-class-members.md). - -## Reference types -A type that is defined as a [class](language-reference/keywords/class.md) is a *reference type*. At run time, when you declare a variable of a reference type, the variable contains the value [null](language-reference/keywords/null.md) until you explicitly create an instance of the object by using the [new](language-reference/keywords/new.md) operator, or assign it an object that has been created elsewhere by using [new](language-reference/keywords/new.md), as shown in the following example: - -[!code-csharp[Reference Types](../../samples/snippets/csharp/concepts/classes/reference-type.cs)] - -When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as *garbage collection*. However, garbage collection is also highly optimized, and in most scenarios, it does not create a performance issue. For more information about garbage collection, see [Automatic memory management and garbage collection](../standard/garbage-collection/gc.md). - -Reference types fully support *inheritance*, a fundamental characteristic of object-oriented programming. When you create a class, you can inherit from any other interface or class that is not defined as [sealed](language-reference/keywords/sealed.md), and other classes can inherit from your class and override your virtual methods. For more information, see [Inheritance](programming-guide/classes-and-structs/inheritance.md). - -## Declaring classes -Classes are declared by using the [class](language-reference/keywords/class.md) keyword, as shown in the following example: - -[!code-csharp[Declaring Classes](../../samples/snippets/csharp/concepts/classes/declaring-classes.cs)] - -The **class** keyword is preceded by the access modifier. Because [public](language-reference/keywords/public.md) is used in this case, anyone can create objects from this class. The name of the class follows the **class** keyword. The remainder of the definition is the class body, where the behavior and data are defined. Fields, properties, methods, and events on a class are collectively referred to as *class members*. - -## Creating objects -A class defines a type of object, but it is not an object itself. An object is a concrete entity based on a class, and is sometimes referred to as an instance of a class. - -Objects can be created by using the [new](language-reference/keywords/new.md) keyword followed by the name of the class that the object will be based on, like this: - -[!code-csharp[Creating Objects](../../samples/snippets/csharp/concepts/classes/creating-objects.cs)] - -When an instance of a class is created, a reference to the object is passed back to the programmer. In the previous example, `object1` is a reference to an object that is based on `Customer`. This reference refers to the new object but does not contain the object data itself. In fact, you can create an object reference without creating an object at all: - -[!code-csharp[Creating Objects](../../samples/snippets/csharp/concepts/classes/creating-objects2.cs)] - -We do not recommend creating object references such as this one that does not refer to an object because trying to access an object through such a reference will fail at run time. However, such a reference can be made to refer to an object, either by creating a new object, or by assigning it to an existing object, such as this: - -[!code-csharp[Creating Objects](../../samples/snippets/csharp/concepts/classes/creating-objects3.cs)] - -This code creates two object references that both refer to the same object. Therefore, any changes to the object made through `object3` will be reflected in subsequent uses of `object4`. Because objects that are based on classes are referred to by reference, classes are known as reference types. - -## Class inheritance -Inheritance is accomplished by using a *derivation*, which means a class is declared by using a *base class* from which it inherits data and behavior. A base class is specified by appending a colon and the name of the base class following the derived class name, like this: - -[!code-csharp[Inheritance](../../samples/snippets/csharp/concepts/classes/inheritance.cs)] - -When a class declares a base class, it inherits all the members of the base class except the constructors. - -Unlike C++, a class in C# can only directly inherit from one base class. However, because a base class may itself inherit from another class, a class may indirectly inherit multiple base classes. Furthermore, a class can directly implement more than one interface. For more information, see [Interfaces](programming-guide/interfaces/index.md). - -A class can be declared [abstract](language-reference/keywords/abstract.md). An abstract class contains abstract methods that have a signature definition but no implementation. Abstract classes cannot be instantiated. They can only be used through derived classes that implement the abstract methods. By contrast, a [sealed](language-reference/keywords/sealed.md) class does not allow other classes to derive from it. For more information, see [Abstract and sealed classes and class members](programming-guide/classes-and-structs/abstract-and-sealed-classes-and-class-members.md). - -Class definitions can be split between different source files. For more information, see [Partial class definitions](programming-guide/classes-and-structs/partial-classes-and-methods.md). - - -## Example -In the following example, a public class that contains a single field, a method, and a special method called a constructor is defined. For more information, see [Constructors](programming-guide/classes-and-structs/constructors.md). The class is then instantiated with the **new** keyword. - -[!code-csharp[Class Example](../../samples/snippets/csharp/concepts/classes/class-example.cs)] - -## C# language specification -For more information, see the [C# language specification](language-reference/language-specification/index.md). The language specification is the definitive source for C# syntax and usage. - -## See also -[C# programming guide](programming-guide/index.md) -[Polymorphism](programming-guide/classes-and-structs/polymorphism.md) -[Class and struct members](programming-guide/classes-and-structs/members.md) -[Class and struct methods](programming-guide/classes-and-structs/methods.md) -[Constructors](programming-guide/classes-and-structs/constructors.md) -[Finalizers](programming-guide/classes-and-structs/destructors.md) -[Objects](programming-guide/classes-and-structs/objects.md) - diff --git a/docs/csharp/programming-guide/classes-and-structs/classes.md b/docs/csharp/programming-guide/classes-and-structs/classes.md index 4fd2175ed17de..2709af86178c1 100644 --- a/docs/csharp/programming-guide/classes-and-structs/classes.md +++ b/docs/csharp/programming-guide/classes-and-structs/classes.md @@ -1,6 +1,7 @@ --- title: "Classes (C# Programming Guide)" -ms.date: 07/20/2015 +description: Learn about the class types and how to create them +ms.date: 04/05/2018 ms.prod: .net ms.technology: - "devlang-csharp" @@ -14,40 +15,69 @@ author: "BillWagner" ms.author: "wiwagn" --- # Classes (C# Programming Guide) -A *class* is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared as static, client code can use it by creating *objects* or *instances* which are assigned to a variable. The variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as [static](../../../csharp/language-reference/keywords/static.md), then only one copy exists in memory and client code can only access it through the class itself, not an *instance variable*. For more information, see [Static Classes and Static Class Members](../../../csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members.md). - - Unlike structs, classes support *inheritance*, a fundamental characteristic of object-oriented programming. For more information, see [Inheritance](../../../csharp/programming-guide/classes-and-structs/inheritance.md). +A *class* is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. A class is like a blueprint. It defines the data and behavior of a type. If the class is not declared as static, client code can create *instances* of it. These instances are *objects* which are assigned to a variable. The instance of a class remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as [static](../../../csharp/language-reference/keywords/static.md), you cannot create instances, and client code can only access it through the class itself. For more information, see [Static Classes and Static Class Members](../../../csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members.md). + +## Reference types +A type that is defined as a [class](../../../csharp/language-reference/keywords/class.md) is a *reference type*. At run time, when you declare a variable of a reference type, the variable contains the value [null](../../../csharp/language-reference/keywords/null.md) until you explicitly create an instance of the class by using the [new](../../../csharp/language-reference/keywords/new.md) operator, or assign it an object that has been created elsewhere, as shown in the following example: + +```csharp +MyClass mc = new MyClass(); +MyClass mc2 = mc; +``` + +When the object is created, the memory is allocated on the managed heap, and the variable holds only a reference to the location of the object. Types on the managed heap require overhead both when they are allocated and when they are reclaimed by the automatic memory management functionality of the CLR, which is known as *garbage collection*. However, garbage collection is also highly optimized, and in most scenarios, it does not create a performance issue. For more information about garbage collection, see [Automatic memory management and garbage collection](../../../standard/garbage-collection/gc.md). ## Declaring Classes - Classes are declared by using the [class](../../../csharp/language-reference/keywords/class.md) keyword, as shown in the following example: - - [!code-csharp[csProgGuideObjects#79](../../../csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_1.cs)] - - The `class` keyword is preceded by the access level. Because [public](../../../csharp/language-reference/keywords/public.md) is used in this case, anyone can create objects from this class. The name of the class follows the `class` keyword. The remainder of the definition is the class body, where the behavior and data are defined. Fields, properties, methods, and events on a class are collectively referred to as *class members*. + Classes are declared by using the [class](../../../csharp/language-reference/keywords/class.md) keyword, as shown in the following example: + + ```csharp + public class Customer + { + // Fields, properties, methods and events go here... + } +``` + + The `class` keyword is preceded by the access level. Because [public](../../../csharp/language-reference/keywords/public.md) is used in this case, anyone can create instances of this class. The name of the class follows the `class` keyword. The remainder of the definition is the class body, where the behavior and data are defined. Fields, properties, methods, and events on a class are collectively referred to as *class members*. ## Creating Objects Although they are sometimes used interchangeably, a class and an object are different things. A class defines a type of object, but it is not an object itself. An object is a concrete entity based on a class, and is sometimes referred to as an instance of a class. Objects can be created by using the [new](../../../csharp/language-reference/keywords/new.md) keyword followed by the name of the class that the object will be based on, like this: - - [!code-csharp[csProgGuideObjects#80](../../../csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_2.cs)] + + ```csharp + Customer object1 = new Customer(); + ``` When an instance of a class is created, a reference to the object is passed back to the programmer. In the previous example, `object1` is a reference to an object that is based on `Customer`. This reference refers to the new object but does not contain the object data itself. In fact, you can create an object reference without creating an object at all: - [!code-csharp[csProgGuideObjects#81](../../../csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_3.cs)] + ```csharp + Customer object2; + ``` We don't recommend creating object references such as this one that don't refer to an object because trying to access an object through such a reference will fail at run time. However, such a reference can be made to refer to an object, either by creating a new object, or by assigning it to an existing object, such as this: + + ```csharp + Customer object3 = new Customer(); + Customer object4 = object3; + ``` - [!code-csharp[csProgGuideObjects#82](../../../csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_4.cs)] - - This code creates two object references that both refer to the same object. Therefore, any changes to the object made through `object3` will be reflected in subsequent uses of `object4`. Because objects that are based on classes are referred to by reference, classes are known as reference types. + This code creates two object references that both refer to the same object. Therefore, any changes to the object made through `object3` are reflected in subsequent uses of `object4`. Because objects that are based on classes are referred to by reference, classes are known as reference types. ## Class Inheritance + + Classes fully support *inheritance*, a fundamental characteristic of object-oriented programming. When you create a class, you can inherit from any other interface or class that is not defined as [sealed](../../../csharp/language-reference/keywords/sealed.md), and other classes can inherit from your class and override class virtual methods. + Inheritance is accomplished by using a *derivation*, which means a class is declared by using a *base class* from which it inherits data and behavior. A base class is specified by appending a colon and the name of the base class following the derived class name, like this: + + ```csharp + public class Manager : Employee + { + // Employee fields, properties, methods and events are inherited + // New Manager fields, properties, methods and events go here... + } + ``` - [!code-csharp[csProgGuideObjects#83](../../../csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_5.cs)] - - When a class declares a base class, it inherits all the members of the base class except the constructors. + When a class declares a base class, it inherits all the members of the base class except the constructors. For more information, see [Inheritance](../../../csharp/programming-guide/classes-and-structs/inheritance.md). Unlike C++, a class in C# can only directly inherit from one base class. However, because a base class may itself inherit from another class, a class may indirectly inherit multiple base classes. Furthermore, a class can directly implement more than one interface. For more information, see [Interfaces](../../../csharp/programming-guide/interfaces/index.md). @@ -59,7 +89,7 @@ A *class* is a construct that enables you to create your own custom types by gro In the following example, a public class that contains a single field, a method, and a special method called a constructor is defined. For more information, see [Constructors](../../../csharp/programming-guide/classes-and-structs/constructors.md). The class is then instantiated with the `new` keyword. ## Example - [!code-csharp[csProgGuideObjects#84](../../../csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_6.cs)] + [!code-csharp[Class Example](~/samples/snippets/csharp/programming-guide/classes-and-structs/class-example.cs)] ## C# Language Specification [!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)] diff --git a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_1.cs b/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_1.cs deleted file mode 100644 index e7b746c3a3d3f..0000000000000 --- a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_1.cs +++ /dev/null @@ -1,4 +0,0 @@ - public class Customer - { - //Fields, properties, methods and events go here... - } \ No newline at end of file diff --git a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_2.cs b/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_2.cs deleted file mode 100644 index 4afc9d65b9bbd..0000000000000 --- a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_2.cs +++ /dev/null @@ -1 +0,0 @@ - Customer object1 = new Customer(); \ No newline at end of file diff --git a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_3.cs b/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_3.cs deleted file mode 100644 index 4378df1b76abb..0000000000000 --- a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_3.cs +++ /dev/null @@ -1 +0,0 @@ - Customer object2; \ No newline at end of file diff --git a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_4.cs b/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_4.cs deleted file mode 100644 index 9abd143587cd6..0000000000000 --- a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_4.cs +++ /dev/null @@ -1,2 +0,0 @@ - Customer object3 = new Customer(); - Customer object4 = object3; \ No newline at end of file diff --git a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_5.cs b/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_5.cs deleted file mode 100644 index cf54ec38c86a1..0000000000000 --- a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_5.cs +++ /dev/null @@ -1,5 +0,0 @@ - public class Manager : Employee - { - // Employee fields, properties, methods and events are inherited - // New Manager fields, properties, methods and events go here... - } \ No newline at end of file diff --git a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_6.cs b/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_6.cs deleted file mode 100644 index 2a0bb5bbda340..0000000000000 --- a/docs/csharp/programming-guide/classes-and-structs/codesnippet/CSharp/classes_6.cs +++ /dev/null @@ -1,47 +0,0 @@ - public class Person - { - // Field - public string name; - - // Constructor that takes no arguments. - public Person() - { - name = "unknown"; - } - - // Constructor that takes one argument. - public Person(string nm) - { - name = nm; - } - - // Method - public void SetName(string newName) - { - name = newName; - } - } - class TestPerson - { - static void Main() - { - // Call the constructor that has no parameters. - Person person1 = new Person(); - Console.WriteLine(person1.name); - - person1.SetName("John Smith"); - Console.WriteLine(person1.name); - - // Call the constructor that has one parameter. - Person person2 = new Person("Sarah Jones"); - Console.WriteLine(person2.name); - - // Keep the console window open in debug mode. - Console.WriteLine("Press any key to exit."); - Console.ReadKey(); - } - } - // Output: - // unknown - // John Smith - // Sarah Jones \ No newline at end of file diff --git a/docs/framework/app-domains/how-to-configure-an-application-domain.md b/docs/framework/app-domains/how-to-configure-an-application-domain.md index ce16a0d0655d5..63d9fb1cef36e 100644 --- a/docs/framework/app-domains/how-to-configure-an-application-domain.md +++ b/docs/framework/app-domains/how-to-configure-an-application-domain.md @@ -40,5 +40,5 @@ You can provide the common language runtime with configuration information for a [!code-vb[ADApplicationBase#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/ADApplicationBase/VB/source2.vb#2)] ## See Also - [Programming with Application Domains](http://msdn.microsoft.com/library/bd36055b-56bd-43eb-b4d8-820c37172131) + [Programming with Application Domains](application-domains.md#programming-with-application-domains) [Using Application Domains](../../../docs/framework/app-domains/use.md) diff --git a/docs/framework/app-domains/how-to-create-an-application-domain.md b/docs/framework/app-domains/how-to-create-an-application-domain.md index 4dca072f7acc3..c6a8dedde425f 100644 --- a/docs/framework/app-domains/how-to-create-an-application-domain.md +++ b/docs/framework/app-domains/how-to-create-an-application-domain.md @@ -36,5 +36,5 @@ A common language runtime host creates application domains automatically when th [!code-vb[ADCreateDomain#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/ADCreateDomain/VB/source2.vb#2)] ## See Also - [Programming with Application Domains](http://msdn.microsoft.com/library/bd36055b-56bd-43eb-b4d8-820c37172131) + [Programming with Application Domains](application-domains.md#programming-with-application-domains) [Using Application Domains](../../../docs/framework/app-domains/use.md) diff --git a/docs/framework/app-domains/how-to-load-assemblies-into-an-application-domain.md b/docs/framework/app-domains/how-to-load-assemblies-into-an-application-domain.md index 0d64b0e55aea0..f334ca11243da 100644 --- a/docs/framework/app-domains/how-to-load-assemblies-into-an-application-domain.md +++ b/docs/framework/app-domains/how-to-load-assemblies-into-an-application-domain.md @@ -54,7 +54,7 @@ There are several ways to load an assembly into an application domain. The recom ## See Also - [Programming with Application Domains](http://msdn.microsoft.com/library/bd36055b-56bd-43eb-b4d8-820c37172131) + [Programming with Application Domains](application-domains.md#programming-with-application-domains) [Reflection](../../../docs/framework/reflection-and-codedom/reflection.md) [Using Application Domains](../../../docs/framework/app-domains/use.md) [How to: Load Assemblies into the Reflection-Only Context](../../../docs/framework/reflection-and-codedom/how-to-load-assemblies-into-the-reflection-only-context.md) diff --git a/docs/framework/app-domains/how-to-unload-an-application-domain.md b/docs/framework/app-domains/how-to-unload-an-application-domain.md index 364cffeb04aa7..4c24bdac819cb 100644 --- a/docs/framework/app-domains/how-to-unload-an-application-domain.md +++ b/docs/framework/app-domains/how-to-unload-an-application-domain.md @@ -38,6 +38,6 @@ When you have finished using an application domain, unload it using the [!NOTE] -This guide was written for F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. - -> [!NOTE] -The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete. - -This walkthrough for F# 3.0 shows you how to access typed data for a SQL database based on the ADO.NET Entity Data Model. This walkthrough shows you how to set up the F# `SqlEntityConnection` type provider for use with a SQL database, how to write queries against the data, how to call stored procedures on the database, as well as how to use some of the ADO.NET Entity Framework types and methods to update the database. - -This walkthrough illustrates the following tasks, which you should perform in this order for the walkthrough to succeed: - - -- Create the School database -
- -- Create and configure an F# project -
- -- Configure the type provider and connect to the Entity Data Model -
- -- Query the database -
- -- Updating the database -
- - -## Prerequisites -You must have access to a server that's running SQL Server where you can create a database to complete these steps. - -## Create the School database -You can create the School database on any server that's running SQL Server to which you have administrative access, or you can use LocalDB. - - -#### To create the School database - -1. In **Server Explorer**, open the shortcut menu for the **Data Connections** node, and then choose **Add Connection**. -
The **Add Connection** dialog box appears. -
- -2. In the **Server name** box, specify the name of an instance of SQL Server to which you have administrative access, or specify (localdb\v11.0) if you don't have access to a server. -
SQL Server Express LocalDB provides a lightweight database server for development and testing on your machine. For more information about LocalDB, see [Walkthrough: Creating a Local Database File in Visual Studio](https://msdn.microsoft.com/library/ms233763.aspx). -
A new node is created in **Server Explorer** under **Data Connections**. -
- -3. Open the shortcut menu for the new connection node, and then choose **New Query**. -
- -4. Open [Creating the School Sample Database](https://msdn.microsoft.com/library/bb399731(v=vs.100).aspx) on the Microsoft website, and then copy and paste the database script that creates the School database into the editor window. -
- - -## - -## Create and configure an F# project -In this step, you create a project and set it up to use a type provider. - - -#### To create and configure an F# project - -1. Close the previous project, create another project, and name it **SchoolEDM**. -
- -2. In **Solution Explorer**, open the shortcut menu for **References**, and then choose **Add Reference**. -
- -3. Choose the **Framework** node, and then, in the **Framework** list, choose **System.Data**, **System.Data.Entity**, and **System.Data.Linq**. -
- -4. Choose the **Extensions** node, add a reference to the [FSharp.Data.TypeProviders](https://msdn.microsoft.com/library/a858f859-047a-44ab-945b-8731d7a0e6e3) assembly, and then choose the **OK** button to dismiss the dialog box. -
- -5. Add the following code to define an internal module and open appropriate namespaces. The type provider can inject types only into a private or internal namespace. -
- -```fsharp -module internal SchoolEDM - -open System.Data.Linq -open System.Data.Entity -open Microsoft.FSharp.Data.TypeProviders -``` - -6. To run the code in this walkthrough interactively as a script instead of as a compiled program, open the shortcut menu for the project node, choose **Add New Item**, add an F# script file, and then add the code in each step to the script. To load the assembly references, add the following lines. -
- -```fsharp -#r "System.Data.Entity.dll" -#r "FSharp.Data.TypeProviders.dll" -#r "System.Data.Linq.dll" -``` - -7. Highlight each block of code as you add it, and choose the Alt + Enter keys to run it in F# Interactive. -
- -## Configure the type provider, and connect to the Entity Data Model -In this step, you set up a type provider with a data connection and obtain a data context that allows you to work with data. - - -#### To configure the type provider, and connect to the Entity Data Model - -1. Enter the following code to configure the `SqlEntityConnection` type provider that generates F# types based on the Entity Data Model that you created previously. Instead of the full EDMX connection string, use only the SQL connection string. -
- -```fsharp -type private EntityConnection = SqlEntityConnection -``` - - This action sets up a type provider with the database connection that you created earlier. The property `MultipleActiveResultSets` is needed when you use the ADO.NET Entity Framework because this property allows multiple commands to execute asynchronously on the database in one connection, which can occur frequently in ADO.NET Entity Framework code. For more information, see [Multiple Active Result Sets (MARS)](/sql/relational-databases/native-client/features/using-multiple-active-result-sets-mars). -
- -2. Get the data context, which is an object that contains the database tables as properties and the database stored procedures and functions as methods. -
- -```fsharp -let context = EntityConnection.GetDataContext() -``` - -## Querying the database -In this step, you use F# query expressions to execute various queries on the database. - - -#### To query the data - -- Enter the following code to query the data from the entity data model. Note the effect of Pluralize = true, which changes the database table Course to Courses and Person to People. -
- -```fsharp -query { - for course in context.Courses do - select course -} |> Seq.iter (fun course -> printfn "%s" course.Title) - -query { - for person in context.People do - select person -} |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName) - -// Add a where clause to filter results. -query { - for course in context.Courses do - where (course.DepartmentID = 1) - select course -} |> Seq.iter (fun course -> printfn "%s" course.Title) - -// Join two tables. -query { - for course in context.Courses do - join dept in context.Departments on (course.DepartmentID = dept.DepartmentID) - select (course, dept.Name) -} |> Seq.iter (fun (course, deptName) -> printfn "%s %s" course.Title deptName) -``` - -## Updating the database -To update the database, you use the Entity Framework classes and methods. You can use two types of data context with the SQLEntityConnection type provider. First, `ServiceTypes.SimpleDataContextTypes.EntityContainer` is the simplified data context, which includes only the provided properties that represent database tables and columns. Second, the full data context is an instance of the Entity Framework class `System.Data.Objects.ObjectContext`, which contains the method `System.Data.Objects.ObjectContext.AddObject(System.String,System.Object)` to add rows to the database. The Entity Framework recognizes the tables and the relationships between them, so it enforces database consistency. - - -#### To update the database - -1. Add the following code to your program. In this example, you add two objects with a relationship between them, and you add an instructor and an office assignment. The table `OfficeAssignments` contains the `InstructorID` column, which references the `PersonID` column in the `Person` table. -
- -```fsharp -// The full data context -let fullContext = context.DataContext - -// A helper function. -let nullable value = new System.Nullable<_>(value) - -let addInstructor(lastName, firstName, hireDate, office) = - let hireDate = DateTime.Parse(hireDate) - let newPerson = new EntityConnection.ServiceTypes.Person(LastName = lastName, - FirstName = firstName, - HireDate = nullable hireDate) - fullContext.AddObject("People", newPerson) - - let newOffice = new EntityConnection.ServiceTypes.OfficeAssignment(Location = office) - - fullContext.AddObject("OfficeAssignments", newOffice) - fullContext.CommandTimeout <- nullable 1000 - fullContext.SaveChanges() |> printfn "Saved changes: %d object(s) modified." - -addInstructor("Parker", "Darren", "1/1/1998", "41/3720") -``` - -Nothing is changed in the database until you call `System.Data.Objects.ObjectContext.SaveChanges`. -
- -2. Now restore the database to its earlier state by deleting the objects that you added. -
- -```fsharp -let deleteInstructor(lastName, firstName) = - query { - for person in context.People do - where (person.FirstName = firstName && - person.LastName = lastName) - select person - } |> Seq.iter (fun person-> - query { - for officeAssignment in context.OfficeAssignments do - where (officeAssignment.Person.PersonID = person.PersonID) - select officeAssignment - } |> Seq.iter (fun officeAssignment -> fullContext.DeleteObject(officeAssignment)) - - fullContext.DeleteObject(person)) - - // The call to SaveChanges should be outside of any iteration on the queries. - fullContext.SaveChanges() |> printfn "Saved changed: %d object(s) modified." - -deleteInstructor("Parker", "Darren") -``` - ->[!WARNING] -When you use a query expression, you must remember that the query is subject to lazy evaluation. Therefore, the database is still open for reading during any chained evaluations, such as in the lambda expression blocks after each query expression. Any database operation that explicitly or implicitly uses a transaction must occur after the read operations have completed. - - -## Next Steps -Explore other query options by reviewing the query operators available in [Query Expressions](../../language-reference/query-expressions.md), and also review the [ADO.NET Entity Framework](https://msdn.microsoft.com/library/bb399572) to understand what functionality is available to you when you use this type provider. - - -## See Also -[Type Providers](index.md) -[SqlEntityConnection Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/sqlentityconnection-type-provider-%5bfsharp%5d) -[Walkthrough: Generating F# Types from an EDMX Schema File](generating-fsharp-types-from-edmx.md) -[ADO.NET Entity Framework](https://msdn.microsoft.com/library/bb399572) -[.edmx File Overview](https://msdn.microsoft.com/library/f4c8e7ce-1db6-417e-9759-15f8b55155d4) -[EDM Generator (EdmGen.exe)](https://msdn.microsoft.com/library/bb387165) diff --git a/docs/fsharp/tutorials/type-providers/accessing-a-sql-database.md b/docs/fsharp/tutorials/type-providers/accessing-a-sql-database.md deleted file mode 100644 index 49a2d1b8689b8..0000000000000 --- a/docs/fsharp/tutorials/type-providers/accessing-a-sql-database.md +++ /dev/null @@ -1,459 +0,0 @@ ---- -title: "Walkthrough: Accessing a SQL Database by Using Type Providers (F#)" -description: Learn how to use the SqlDataConnection (LINQ to SQL) type provider in F# 3.0 to generate types for a SQL database when you have a live database connection. -keywords: visual f#, f#, functional programming -author: cartermp -ms.author: phcart -ms.date: 05/16/2016 -ms.topic: language-reference -ms.prod: .net -ms.technology: devlang-fsharp -ms.devlang: fsharp -ms.assetid: 1c413eb0-16a5-4c1a-9a4e-ad6877e645d6 ---- - -# Walkthrough: Accessing a SQL Database by Using Type Providers - -> [!NOTE] -This guide was written for F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. - -> [!NOTE] -The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete. - -This walkthrough explains how to use the SqlDataConnection (LINQ to SQL) type provider that is available in F# 3.0 to generate types for data in a SQL database when you have a live connection to a database. If you do not have a live connection to a database, but you do have a LINQ to SQL schema file (DBML file), see [Walkthrough: Generating F# Types from a DBML File](generating-fsharp-types-from-dbml.md). - -This walkthrough illustrates the following tasks. These tasks must be performed in this order for the walkthrough to succeed: - - -- Preparing a test database - -- Creating the project - -- Setting up a type provider - -- Querying the data - -- Working with nullable fields - -- Calling a stored procedure - -- Updating the database - -- Executing Transact-SQL code - -- Using the full data context - -- Deleting data - -- Create a test database (as needed) - -## Preparing a Test Database -On a server that's running SQL Server, create a database for testing purposes. You can use the database create script at the bottom of this page in the section [Creating a test database](#creating-a-test-database) to do this. - - -#### To prepare a test database - -To run the MyDatabase Create Script, open the **View** menu, and then choose **SQL Server Object Explorer** or choose the Ctrl+\, Ctrl+S keys. In **SQL Server Object Explorer** window, open the shortcut menu for the appropriate instance, choose **New Query**, copy the script at the bottom of this page, and then paste the script into the editor. To run the SQL script, choose the toolbar icon with the triangular symbol, or choose the Ctrl+Q keys. For more information about **SQL Server Object Explorer**, see [Connected Database Development](https://msdn.microsoft.com/library/hh272679(VS.103).aspx). - - -## Creating the project -Next, you create an F# application project. - - -#### To create and set up the project - -1. Create a new F# Application project. - -2. Add references to [FSharp.Data.TypeProviders](https://msdn.microsoft.com/library/a858f859-047a-44ab-945b-8731d7a0e6e3), as well as `System.Data`, and `System.Data.Linq`. - -3. Open the appropriate namespaces by adding the following lines of code to the top of your F# code file Program.fs. - - ```fsharp -open System -open System.Data -open System.Data.Linq -open Microsoft.FSharp.Data.TypeProviders -open Microsoft.FSharp.Linq -``` - -4. As with most F# programs, you can execute the code in this walkthrough as a compiled program, or you can run it interactively as a script. If you prefer to use scripts, open the shortcut menu for the project node, select **Add New Item**, add an F# script file, and add the code in each step to the script. You will need to add the following lines at the top of the file to load the assembly references. - - ```fsharp -#r "System.Data.dll" -#r "FSharp.Data.TypeProviders.dll" -#r "System.Data.Linq.dll" -``` - - You can then select each block of code as you add it and press Alt+Enter to run it in F# Interactive. - -## Setting up a type provider -In this step, you create a type provider for your database schema. - - -#### To set up the type provider from a direct database connection - -There are two critical lines of code that you need in order to create the types that you can use to query a SQL database using the type provider. First, you instantiate the type provider. To do this, create what looks like a type abbreviation for a `SqlDataConnection` with a static generic parameter. `SqlDataConnection` is a SQL type provider, and should not be confused with `SqlConnection` type that is used in ADO.NET programming. If you have a database that you want to connect to, and have a connection string, use the following code to invoke the type provider. Substitute your own connection string for the example string given. For example, if your server is MYSERVER and the database instance is INSTANCE, the database name is MyDatabase, and you want to use Windows Authentication to access the database, then the connection string would be as given in the following example code. - -```fsharp -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 -``` - -Now you have a type, `dbSchema`, which is a parent type that contains all the generated types that represent database tables. You also have an object, `db`, which has as its members all the tables in the database. The table names are properties, and the type of these properties is generated by the F# compiler. The types themselves appear as nested types under `dbSchema.ServiceTypes`. Therefore, any data retrieved for rows of these tables is an instance of the appropriate type that was generated for that table. The name of the type is `ServiceTypes.Table1`. - -To familiarize yourself with how the F# language interprets queries into SQL queries, review the line that sets the `Log` property on the data context. - -To further explore the types created by the type provider, add the following code. - -```fsharp -let table1 = db.Table1 -``` - -Hover over `table1` to see its type. Its type is `System.Data.Linq.Table` and the generic argument implies that the type of each row is the generated type, `dbSchema.ServiceTypes.Table1`. The compiler creates a similar type for each table in the database. - -## Querying the data -In this step, you write a query using F# query expressions. - - -#### To query the data - -1. Now create a query for that table in the database. Add the following code. - - ```fsharp - let query1 = - query { - for row in db.Table1 do - select row - } - query1 |> Seq.iter (fun row -> printfn "%s %d" row.Name row.TestData1) -``` - - The appearance of the word `query` indicates that this is a query expression, a type of computation expression that generates a collection of results similar of a typical database query. If you hover over query, you will see that it is an instance of [Linq.QueryBuilder Class](https://msdn.microsoft.com/visualfsharpdocs/conceptual/linq.querybuilder-class-%5bfsharp%5d), a type that defines the query computation expression. If you hover over `query1`, you will see that it is an instance of `System.Linq.IQueryable`. As the name suggests, `System.Linq.IQueryable` represents data that may be queried, not the result of a query. A query is subject to lazy evaluation, which means that the database is only queried when the query is evaluated. The final line passes the query through `Seq.iter`. Queries are enumerable and may be iterated like sequences. For more information, see [Query Expressions](../../language-reference/query-expressions.md). - -2. Now add a query operator to the query. There are a number of query operators available that you can use to construct more complex queries. This example also shows that you can eliminate the query variable and use a pipeline operator instead. - - ```fsharp - 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. Add a more complex query with a join of two tables. - - ```fsharp - 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. In real-world code, the parameters in your query are usually values or variables, not compile-time constants. Add the following code that wraps a query in a function that takes a parameter, and then calls that function with the value 10. - - ```fsharp - 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) -``` - -## Working with nullable fields -In databases, fields often allow null values. In the .NET type system, you cannot use the ordinary numerical data types for data that allows nulls because those types do not have null as a possible value. Therefore, these values are represented by instances of `System.Nullable` type. Instead of accessing the value of such fields directly with the name of the field, you need to add some extra steps. You can use the `System.Nullable.Value` property to access the underlying value of a nullable type. The `System.Nullable.Value` property throws an exception if the object is null rather than having a value. You can use the `System.Nullable.HasValue` Boolean method to determine if a value exists, or use `System.Nullable.GetValueOrDefault()` to ensure that you have an actual value in all cases. If you use `System.Nullable.GetValueOrDefault()` and there is a null in the database, then it is replaced with a value such as an empty string for string types, 0 for integral types or 0.0 for floating point types. - -When you need to perform equality tests or comparisons on nullable values in a `where` clause in a query, you can use the nullable operators found in the [Linq.NullableOperators Module](https://msdn.microsoft.com/visualfsharpdocs/conceptual/linq.nullableoperators-module-%5bfsharp%5d). These are like the regular comparison operators `=`, `>`, `<=`, and so on, except that a question mark appears on the left or right of the operator where the nullable values are. For example, the operator `>?` is a greater-than operator with a nullable value on the right. The way these operators work is that if either side of the expression is null, the expression evaluates to `false`. In a `where` clause, this generally means that the rows that contain null fields are not selected and not returned in the query results. - - -#### To work with nullable fields - -The following code shows working with nullable values; assume that **TestData1** is an integer field that allows nulls. - -```fsharp -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) -``` - -## Calling a stored procedure -Any stored procedures on the database can be called from F#. You must set the static parameter `StoredProcedures` to `true` in the type provider instantiation. The type provider `SqlDataConnection` contains several static methods that you can use to configure the types that are generated. For a complete description of these, see [SqlDataConnection Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/sqldataconnection-type-provider-%5bfsharp%5d). A method on the data context type is generated for each stored procedure. - - -#### To call a stored procedure - -If the stored procedures takes parameters that are nullable, you need to pass an appropriate `System.Nullable` value. The return value of a stored procedure method that returns a scalar or a table is `System.Data.Linq.ISingleResult`, which contains properties that enable you to access the returned data. The type argument for `System.Data.Linq.ISingleResult` depends on the specific procedure and is also one of the types that the type provider generates. For a stored procedure named `Procedure1`, the type is `Procedure1Result`. The type `Procedure1Result` contains the names of the columns in a returned table, or, for a stored procedure that returns a scalar value, it represents the return value. - -The following code assumes that there is a procedure `Procedure1` on the database that takes two nullable integers as parameters, runs a query that returns a column named `TestData1`, and returns an integer. - -```fsharp -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) -``` - -## Updating the database -The LINQ DataContext type contains methods that make it easier to perform transacted database updates in a fully typed fashion with the generated types. - - -#### To update the database - -1. In the following code, several rows are added to the database. If you are only adding a row, you can use `System.Data.Linq.Table.InsertOnSubmit()` to specify the new row to add. If you are inserting multiple rows, you should put them into a collection and call `System.Data.Linq.Table.InsertAllOnSubmit(System.Collections.Generic.IEnumerable)`. When you call either of these methods, the database is not immediately changed. You must call `System.Data.Linq.DataContext.SubmitChanges` to actually commit the changes. By default, everything that you do before you call `System.Data.Linq.DataContext.SubmitChanges` is implicitly part of the same transaction. - - ```fsharp - 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. Now clean up the rows by calling a delete operation. - - ```fsharp - // 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 -``` - -## Executing Transact-SQL code -You can also specify Transact-SQL directly by using the `System.Data.Linq.DataContext.ExecuteCommand(System.String,System.Object[])` method on the `DataContext` class. - - -#### To execute custom SQL commands - -The following code shows how to send SQL commands to insert a record into a table and also to delete a record from a table. - -```fsharp -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 -``` - -## Using the full data context -In the previous examples, the `GetDataContext` method was used to get what is called the *simplified data context* for the database schema. The simplified data context is easier to use when you are constructing queries because there are not as many members available. Therefore, when you browse the properties in IntelliSense, you can focus on the database structure, such as the tables and stored procedures. However, there is a limit to what you can do with the simplified data context. A full data context that provides the ability to perform other actions. is also available This is located in the `ServiceTypes` and has the name of the *DataContext* static parameter if you provided it. If you did not provide it, the name of the data context type is generated for you by SqlMetal.exe based on the other input. The full data context inherits from `System.Data.Linq.DataContext` and exposes the members of its base class, including references to ADO.NET data types such as the `Connection` object, methods such as `System.Data.Linq.DataContext.ExecuteCommand(System.String,System.Object[])` and `System.Data.Linq.DataContext.ExecuteQuery(System.String,System.Object[])` that you can use to write queries in SQL, and also a means to work with transactions explicitly. - - -#### To use the full data context - -The following code demonstrates getting a full data context object and using it to execute commands directly against the database. In this case, two commands are executed as part of the same transaction. - -```fsharp -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() -``` - -## Deleting data -This step shows you how to delete rows from a data table. - - -#### To delete rows from the database - -Now, clean up any added rows by writing a function that deletes rows from a specified table, an instance of the `System.Data.Linq.Table` class. Then write a query to find all the rows that you want to delete, and pipe the results of the query into the `deleteRows` function. This code takes advantage of the ability to provide partial application of function arguments. - -```fsharp -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." -``` - -## Creating a test database -This section shows you how to set up the test database to use in this walkthrough. - -Note that if you alter the database in some way, you will have to reset the type provider. To reset the type provider, rebuild or clean the project that contains the type provider. - - -#### To create the test database - -1. In **Server Explorer**, open the shortcut menu for the **Data Connections** node, and choose **Add Connection**. The **Add Connection** dialog box appears. - -2. In the **Server name** box, specify the name of an instance of SQL Server that you have administrative access to, or if you do not have access to a server, specify (localdb\v11.0). SQL Express LocalDB provides a lightweight database server for development and testing on your machine. A new node is created in **Server Explorer** under **Data Connections**. For more information about LocalDB, see [Walkthrough: Creating a Local Database File in Visual Studio](https://msdn.microsoft.com/library/ms233763.aspx). - -3. Open the shortcut menu for the new connection node, and select **New Query**. - -4. Copy the following SQL script, paste it into the query editor, and then choose the **Execute** button on the toolbar or choose the Ctrl+Shift+E keys. - -```sql -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 the Table2 table. -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 the Table3 table. -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 - -USE MyDatabase - --- Insert data into the Table1 table. -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 data into the Table3 table. -INSERT INTO Table3 (Id, Name, Data) - VALUES (1, 'Testing1', 10); -INSERT INTO Table3 (Id, Name, Data) - VALUES (2, 'Testing2', 100); -``` - - -## See Also -[Type Providers](index.md) - -[SqlDataConnection Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/sqldataconnection-type-provider-%5bfsharp%5d) - -[Walkthrough: Generating F# Types from a DBML File](generating-fsharp-types-from-dbml.md) - -[Query Expressions](../../language-reference/query-expressions.md) - -[LINQ to SQL](../../../../docs/framework/data/adonet/sql/linq/index.md) - -[SqlMetal.exe (Code Generation Tool)](https://msdn.microsoft.com/library/bb386987) diff --git a/docs/fsharp/tutorials/type-providers/accessing-a-web-service.md b/docs/fsharp/tutorials/type-providers/accessing-a-web-service.md deleted file mode 100644 index 9865da3b3fc8d..0000000000000 --- a/docs/fsharp/tutorials/type-providers/accessing-a-web-service.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Walkthrough - Accessing a Web Service by Using Type Providers (F#) -description: Learn how to use the Web Services Description Language (WSDL) type provider available in F# 3.0 to access a WSDL service. -keywords: visual f#, f#, functional programming -author: cartermp -ms.author: phcart -ms.date: 05/16/2016 -ms.topic: language-reference -ms.prod: .net -ms.technology: devlang-fsharp -ms.devlang: fsharp -ms.assetid: 63374fa9-8fb8-43ac-bcb9-ef2290d9f851 ---- - -# Walkthrough: Accessing a Web Service by Using Type Providers - -> [!NOTE] -This guide was written for F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. - -> [!NOTE] -The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete. - -This walkthrough shows you how to use the Web Services Description Language (WSDL) type provider that is available in F# 3.0 to access a WSDL service. In other .NET languages, you generate the code to access the web service by calling svcutil.exe, or by adding a web reference in, for example, a C# project to get Visual Studio to call svcutil.exe for you. In F#, you have the additional option of using the WSDL type provider, so as soon as you write the code that creates the WsdlService type, the types are generated and become available. This process relies on the service being available when you are writing the code. - -This walkthrough illustrates the following tasks. You must complete them in this order for the walkthrough to succeed: - - -- Creating the project -
- -- Configuring the type provider -
- -- Calling the web service, and processing the results -
- - -## Creating the project -In the step, you create a project and add the appropriate references to use a WSDL type provider. - - -#### To create and set up an F# project - -1. Open a new F# Console Application project. -
- -2. In **Solution Explorer**, open the shortcut menu for the project's **Reference** node, and then choose **Add Reference**. -
- -3. In the **Assemblies** area, choose **Framework**, and then, in the list of available assemblies, choose **System.Runtime.Serialization** and **System.ServiceModel**. -
- -4. In the **Assemblies** area, choose **Extensions**. -
- -5. In the list of available assemblies, choose **FSharp.Data.TypeProviders**, and then choose the **OK** button to add references to these assemblies. -
- -## Configuring the type provider -In this step, you use the WSDL type provider to generate types for the TerraServer web service. - - -#### To configure the type provider and generate types - -1. Add the following line of code to open the type provider namespace. -
- -```fsharp -open System -open System.ServiceModel -open Microsoft.FSharp.Linq -open Microsoft.FSharp.Data.TypeProviders -``` - -2. Add the following line of code to invoke the type provider with a web service. In this example, use the TerraServer web service. -
- -```fsharp -type TerraService = WsdlService<" HYPERLINK "https://terraserver-usa.com/TerraService2.asmx?WSDL" https://msrmaps.com/TerraService2.asmx?WSDL"> -``` - - A red squiggle appears under this line of code if the service URI is misspelled or if the service itself is down or isn’t performing. If you point to the code, an error message describes the problem. You can find the same information in the **Error List** window or in the **Output Window** after you build. -
There are two ways to specify configuration settings for a WSDL connection, by using the app.config file for the project, or by using the static type parameters in the type provider declaration. You can use svcutil.exe to generate appropriate configuration file elements. For more information about using svcutil.exe to generate configuration information for a web service, see [ServiceModel Metadata Utility Tool (Svcutil.exe)](https://msdn.microsoft.com/library/aa347733.aspx). For a full description of the static type parameters for the WSDL type provider, see [WsdlService Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/wsdlservice-type-provider-%5bfsharp%5d). -
- -## Calling the web service, and processing the results -Each web service has its own set of types that are used as parameters for its method calls. In this step, you prepare these parameters, call a web method, and process the information that it returns. - - -#### To call the web service, and process the results - -1. The web service might time out or stop functioning, so you should include the web service call in an exception handling block. Write the following code to try to get data from the web service. -
- -```fsharp -try - let terraClient = TerraService.GetTerraServiceSoap () - let myPlace = new TerraService.ServiceTypes.msrmaps.com.Place(City = "Redmond", State = "Washington", Country = "United States") - let myLocation = terraClient.ConvertPlaceToLonLatPt(myPlace) - printfn "Redmond Latitude: %f Longitude: %f" (myLocation.Lat) (myLocation.Lon) -with -| :? ServerTooBusyException as exn -> - let innerMessage = - match (exn.InnerException) with - | null -> "" - | innerExn -> innerExn.Message - printfn "An exception occurred:\n %s\n %s" exn.Message innerMessage -| exn -> printfn "An exception occurred: %s" exn.Message -``` - -Notice that you create the data types that are needed for the web service, such as **Place** and **Location**, as nested types under the WsdlService type **TerraService**. -
- - -## See Also -[WsdlService Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/wsdlservice-type-provider-%5bfsharp%5d) - -[Type Providers](index.md) diff --git a/docs/fsharp/tutorials/type-providers/accessing-an-odata-service.md b/docs/fsharp/tutorials/type-providers/accessing-an-odata-service.md deleted file mode 100644 index b6cc4843e08d6..0000000000000 --- a/docs/fsharp/tutorials/type-providers/accessing-an-odata-service.md +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: "Walkthrough: Accessing an OData Service by Using Type Providers (F#)" -description: Learn how to use the F# ODataService type provider in F# 3.0 to generate client types for an OData service and query data feeds that the service provides. -keywords: visual f#, f#, functional programming -author: cartermp -ms.author: phcart -ms.date: 05/16/2016 -ms.topic: language-reference -ms.prod: .net -ms.technology: devlang-fsharp -ms.devlang: fsharp -ms.assetid: 0adae84c-b0fa-455f-994b-274ecdc6df30 ---- - -# Walkthrough: Accessing an OData Service by Using Type Providers - -> [!NOTE] -This guide was written for F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. - -> [!NOTE] -The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete. - -OData, meaning Open Data Protocol, is a protocol for transferring data over the Internet. Many data providers expose access to their data by publishing an OData web service. You can access data from any OData source in F# 3.0 using data types that are automatically generated by the `ODataService` type provider. For more information about OData, see https://msdn.microsoft.com/library/da3380cc-f6da-4c6c-bdb2-bb86afa59d62. - -This walkthrough shows you how to use the F# ODataService type provider to generate client types for an OData service and query data feeds that the service provides. - -This walkthrough illustrates the following tasks, which you should perform in this order for the walkthrough to succeed: - - -- Configuring a client project for an OData service -
- -- Accessing OData types -
- -- Querying an OData service -
- -- Verifying the OData requests -
- - -## Configuring a client project for an OData service -In this step, you set up a project to use an OData type provider. - - -#### To configure a client project for an OData service - -- Open an F# Console Application project, and then add a reference to the `System.Data.Services.Client` Framework assembly. -
- -- Under `Extensions`, add a reference to the `FSharp.Data.TypeProviders` assembly. -
- -## Accessing OData types -In this step, you create a type provider that provides access to the types and data for an OData service. - - -#### To access OData types - -- In the Code Editor, open an F# source file, and enter the following code. -
- -```fsharp -open Microsoft.FSharp.Data.TypeProviders - - -type Northwind = ODataService<"https://services.odata.org/Northwind/Northwind.svc/"> - -let db = Northwind.GetDataContext() -let fullContext = Northwind.ServiceTypes.NorthwindEntities() -``` - -In this example, you have invoked the F# type provider and instructed it to create a set of types that are based on the OData URI that you specified. Two objects are available that contain information about the data; one is a simplified data context, `db` in the example. This object contains only the data types that are associated with the database, which include types for tables or feeds. The other object, `fullContext` in this example, is an instance of `System.Data.Linq.DataContext` and contains many additional properties, methods, and events. -
- - -## Querying an OData service -In this step, you use F# query expressions to query the OData service. - - -#### To query an OData service - -1. Now that you've set up the type provider, you can query an OData service. -
OData supports only a subset of the available query operations. The following operations and their corresponding keywords are supported: -
- - projection (`select`) -
- - - filtering (`where`, by using string and date operations) -
- - - paging (`skip`, `take`) -
- - - ordering (`orderBy`, `thenBy`) -
- - - `AddQueryOption` and `Expand`, which are OData-specific operations -
- - For more information, see [LINQ Considerations (WCF Data Services)](https://msdn.microsoft.com/library/ee622463.aspx). -
If you want all of the entries in a feed or table, use the simplest form of the query expression, as in the following code: -
- -```fsharp -query { - for customer in db.Customers do - select customer -} |> Seq.iter (fun customer -> - printfn "ID: %s\nCompany: %s" customer.CustomerID customer.CompanyName - printfn "Contact: %s\nAddress: %s" customer.ContactName customer.Address - printfn " %s, %s %s" customer.City customer.Region customer.PostalCode - printfn "%s\n" customer.Phone) -``` - -2. Specify the fields or columns that you want by using a tuple after the select keyword. -
- -```fsharp - query { - for cat in db.Categories do - select (cat.CategoryID, cat.CategoryName, cat.Description) - } |> Seq.iter (fun (id, name, description) -> - printfn "ID: %d\nCategory: %s\nDescription: %s\n" id name description) -``` - -3. Specify conditions by using a `where` clause. -
- -```fsharp -query { - for employee in db.Employees do - where (employee.EmployeeID = 9) - select employee -} |> Seq.iter (fun employee -> - printfn "Name: %s ID: %d" (employee.FirstName + " " + employee.LastName) (employee.EmployeeID)) -``` - -4. Specify a substring condition to the query by using the `System.String.Contains(System.String)` method. The following query returns all products that have "Chef" in their names. Also notice the use of `System.Nullable<'T>.GetValueOrDefault()`. The `UnitPrice` is a nullable value, so you must either get the value by using the `Value` property, or you must call `System.Nullable<'T>.GetValueOrDefault()`. -
- -```fsharp -query { - for product in db.Products do - where (product.ProductName.Contains("Chef")) - select product -} |> Seq.iter (fun product -> - printfn "ID: %d Product: %s" product.ProductID product.ProductName - printfn "Price: %M\n" (product.UnitPrice.GetValueOrDefault())) -``` - -5. Use the `System.String.EndsWith(System.String)` method to specify that a string ends with a certain substring. -
- -```fsharp -query { - for product in db.Products do - where (product.ProductName.EndsWith("u")) - select product -} |> Seq.iter (fun product -> - printfn "ID: %d Product: %s" product.ProductID product.ProductName - printfn "Price: %M\n" (product.UnitPrice.GetValueOrDefault())) -``` - -6. Combine conditions in a where clause by using the `&&` operator. -
- -```fsharp -// Open this module to use the nullable operators ?> and ?<. -open Microsoft.FSharp.Linq.NullableOperators - -let salesIn1997 = query { - for sales in db.Category_Sales_for_1997 do - where (sales.CategorySales ?> 50000.00M && sales.CategorySales ?< 60000.0M) - select sales } - -salesIn1997 -|> Seq.iter (fun sales -> - printfn "Category: %s Sales: %M" sales.CategoryName (sales.CategorySales.GetValueOrDefault())) -``` - -The operators `?>` and `?<` are nullable operators. You can use a full set of nullable equality and comparison operators. For more information, see [Linq.NullableOperators Module](https://msdn.microsoft.com/visualfsharpdocs/conceptual/linq.nullableoperators-module-%5bfsharp%5d). -
- -7. Use the `sortBy` query operator to specify ordering, and use `thenBy` to specify another level of ordering. Notice also the use of a tuple in the select part of the query. Therefore, the query has a tuple as an element type. -
- -```fsharp -printfn "Freight for some orders: " - -query { - for order in db.Orders do - sortBy (order.OrderDate.Value) - thenBy (order.OrderID) - select (order.OrderDate, order.OrderID, order.Customer.CompanyName) -} |> Seq.iter (fun (orderDate, orderID, company) -> - printfn "OrderDate: %s" (orderDate.GetValueOrDefault().ToString()) - printfn "OrderID: %d Company: %s\n" orderID company) -``` - -8. Ignore a specified number of records by using the skip operator, and use the take operator to specify a number of records to return. In this way, you can implement paging on data feeds. -
- -```fsharp -printfn "Get the first page of 2 employees." - -query { - for employee in db.Employees do - take 2 - select employee -} |> Seq.iter (fun employee -> - printfn "Name: %s ID: %d" (employee.FirstName + " " + employee.LastName) (employee.EmployeeID)) - -printfn "Get the next 2 employees." - -query { - for employee in db.Employees do - skip 2 - take 2 - select employee -} |> Seq.iter (fun employee -> - printfn "Name: %s ID: %d" (employee.FirstName + " " + employee.LastName) (employee.EmployeeID)) -``` - -## Verifying the OData request -Every OData query is translated into a specific OData request URI. You can verify that URI, perhaps for debugging purposes, by adding an event handler to the `SendingRequest` event on the full data context object. - - -#### To verify the OData request - -- To verify the OData request URI, use the following code: -
- -```fsharp -// The DataContext property returns the full data context. -db.DataContext.SendingRequest.Add (fun eventArgs -> printfn "Requesting %A" eventArgs.Request.RequestUri) -``` - -The output of the previous code is: -
`requesting https://services.odata.org/Northwind/Northwind.svc/Orders()?$orderby=ShippedDate&$select=OrderID,ShippedDate` - - -## See Also -[Query Expressions](../../language-reference/query-expressions.md) - -[LINQ Considerations (WCF Data Services)](https://msdn.microsoft.com/library/ee622463.aspx) - -[ODataService Type Provider (F#)](https://msdn.microsoft.com/visualfsharpdocs/conceptual/odataservice-type-provider-%5bfsharp%5d) diff --git a/docs/fsharp/tutorials/type-providers/creating-a-type-provider.md b/docs/fsharp/tutorials/type-providers/creating-a-type-provider.md index 66f95a3c9888e..5dc0a457ecb84 100644 --- a/docs/fsharp/tutorials/type-providers/creating-a-type-provider.md +++ b/docs/fsharp/tutorials/type-providers/creating-a-type-provider.md @@ -1,5 +1,5 @@ --- -title: "Tutorial: Creating a Type Provider (F#)" +title: "Tutorial: Create a Type Provider (F#)" description: Learn how to create your own F# type providers in F# 3.0 by examining several simple type providers to illustrate the basic concepts. keywords: visual f#, f#, functional programming author: cartermp @@ -12,7 +12,7 @@ ms.devlang: fsharp ms.assetid: 82bec076-19d4-470c-979f-6c3a14b7c70a --- -# Tutorial: Creating a Type Provider +# Tutorial: Create a Type Provider The type provider mechanism in F# is a significant part of its support for information rich programming. This tutorial explains how to create your own type providers by walking you through the development of several simple type providers to illustrate the basic concepts. For more information about the type provider mechanism in F#, see [Type Providers](index.md). diff --git a/docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-dbml.md b/docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-dbml.md deleted file mode 100644 index 986fa20320164..0000000000000 --- a/docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-dbml.md +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: "Walkthrough: Generating F# Types from a DBML File (F#)" -description: Learn how to create F# types for data from a database in F# 3.0 when you have schema information encoded in a .dbml file. -keywords: visual f#, f#, functional programming -author: cartermp -ms.author: phcart -ms.date: 05/16/2016 -ms.topic: language-reference -ms.prod: .net -ms.technology: devlang-fsharp -ms.devlang: fsharp -ms.assetid: 6fbb6ccc-248f-4226-95e9-f6f99541dbe4 ---- - -# Walkthrough: Generating F# Types from a DBML File - -> [!NOTE] -This guide was written for F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. - -> [!NOTE] -The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete. - -This walkthrough for F# 3.0 describes how to create types for data from a database when you have schema information encoded in a .dbml file. LINQ to SQL uses this file format to represent database schema. You can generate a LINQ to SQL schema file in Visual Studio by using the Object Relational (O/R) Designer. For more information, see [O/R Designer Overview](https://msdn.microsoft.com/library/bb384511.aspx) and [Code Generation in LINQ to SQL](../../../../docs/framework/data/adonet/sql/linq/index.md). - -The Database Markup Language (DBML) type provider allows you to write code that uses types based on a database schema without requiring you to specify a static connection string at compile time. That can be useful if you need to allow for the possibility that the final application will use a different database, different credentials, or a different connection string than the one you use to develop the application. If you have a direct database connection that you can use at compile time and this is the same database and credentials that you will eventually use in your built application, you can also use the SQLDataConnection type provider. For more information, see [Walkthrough: Accessing a SQL Database by Using Type Providers](accessing-a-sql-database.md). - -This walkthrough illustrates the following tasks. They should be completed in this order for the walkthrough to succeed: - - -- Creating a .dbml file -
- -- Creating and setting up an F# project -
- -- Configuring the type provider and generating the types -
- -- Querying the database -
- - -## Prerequisites - -## Creating a .dbml file -If you do not have a database to test on, create one by following the instructions at the bottom of [Walkthrough: Accessing a SQL Database by Using Type Providers](accessing-a-sql-database.md). If you follow these instructions, you will create a database called MyDatabase that contains a few simple tables and stored procedures on your SQL Server. - -If you already have a .dbml file, you can skip to the section, **Create and Set Up an F# Project**. Otherwise, you can create a .dbml file given an existing SQL database and by using the command-line tool SqlMetal.exe. - - -#### To create a .dbml file by using SqlMetal.exe - -1. Open a **Developer Command Prompt**. -
- -2. Ensure that you have access to SqlMetal.exe by entering `SqlMetal.exe /?` at the command prompt. SqlMetal.exe is typically installed under the **Microsoft SDKs** folder in **Program Files** or **Program Files (x86)**. -
- -3. Run SqlMetal.exe with the following command-line options. Substitute an appropriate path in place of `c:\destpath` to create the .dbml file, and insert appropriate values for the database server, instance name, and database name. -
- -``` - SqlMetal.exe /sprocs /dbml:C:\destpath\MyDatabase.dbml /server:SERVER\INSTANCE /database:MyDatabase -``` - ->[!NOTE] -If SqlMetal.exe has trouble creating the file due to permissions issues, change the current directory to a folder that you have write access to. - - -4. You can also look at the other available command-line options. For example, there are options you can use if you want views and SQL functions included in the generated types. For more information, see [SqlMetal.exe (Code Generation Tool)](https://msdn.microsoft.com/library/bb386987). -
- - -## Creating and setting up an F# project -In this step, you create a project and add appropriate references to use the DBML type provider. - - -#### To create and set up an F# project - -1. Add a new F# Console Application project to your solution. -
- -2. In **Solution Explorer**, open the shortcut menu for **References**, and then choose **Add Reference**. -
- -3. In the **Assemblies** area, choose the **Framework** node, and then, in the list of available assemblies, choose the **System.Data** and **System.Data.Linq** assemblies. -
- -4. In the **Assemblies** area, choose **Extensions**, and then, in the list of available assemblies, choose **FSharp.Data.TypeProviders**. -
- -5. Choose the **OK** button to add references to these assemblies to your project. -
- -6. (Optional). Copy the .dbml file that you created in the previous step, and paste the file in the main folder for your project. This folder contains the project file (.fsproj) and code files. On the menu bar, choose **Project**, **Add Existing Item**, and then specify the .dbml file to add it to your project. If you complete these steps, you can omit the ResolutionFolder static parameter in the next step. -
- -## Configuring the type provider -In this section, you create a type provider and generate types from the schema that’s described in the .dbml file. - - -#### To configure the type provider and generate the types - -- Add code that opens the **TypeProviders** namespace and instantiates the type provider for the .dbml file that you want to use. If you added the .dbml file to your project, you can omit the ResolutionFolder static parameter. -
- -```fsharp -open Microsoft.FSharp.Data.TypeProviders - - -type dbml = DbmlFile<"MyDatabase.dbml", ResolutionFolder = @""> - -// This connection string can be specified at run time. -let connectionString = "Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;" -let dataContext = new dbml.Mydatabase(connectionString) -``` - -The DataContext type provides access to all the generated types and inherits from `System.Data.Linq.DataContext`. The DbmlFile type provider has various static parameters that you can set. For example, you can use a different name for the DataContext type by specifying `DataContext=MyDataContext`. In that case, your code resembles the following example: -
- -```fsharp -open Microsoft.FSharp.Data.TypeProviders - - -type dbml = DbmlFile<"MyDatabase.dbml", ContextTypeName = "MyDataContext"> - -// This connection string can be specified at run time. -let connectionString = "Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;" -let db = new dbml.MyDataContext(connectionString) -``` - -## Querying the database -In this section, you use F# query expressions to query the database. - - -#### To query the data - -- Add code to query the database. -
- -```fsharp - query { - for row in db.Table1 do - where (row.TestData1 > 2) - select row - } |> Seq.iter (fun row -> printfn "%d %s" row.TestData1 row.Name) -``` - -## Next Steps -You can proceed to use other query expressions, or get a database connection from the data context and perform normal ADO.NET data operations. For additional steps, see the sections after "Query the Data" in [Walkthrough: Accessing a SQL Database by Using Type Providers](accessing-a-sql-database.md). - - -## See Also -[DbmlFile Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/dbmlfile-type-provider-%5bfsharp%5d) - -[Type Providers](index.md) - -[Walkthrough: Accessing a SQL Database by Using Type Providers](accessing-a-sql-database.md) - -[SqlMetal.exe (Code Generation Tool)](https://msdn.microsoft.com/library/bb386987) - -[Query Expressions](../../language-reference/query-expressions.md) diff --git a/docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-edmx.md b/docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-edmx.md deleted file mode 100644 index 45727156ba6ac..0000000000000 --- a/docs/fsharp/tutorials/type-providers/generating-fsharp-types-from-edmx.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -title: "Walkthrough: Generating F# Types from an EDMX Schema File (F#)" -description: Learn how to create F# types for data represented by the Entity Data Model (EDM) in F# 3.0, where the schema is specified in an .edmx file. -keywords: visual f#, f#, functional programming -author: cartermp -ms.author: phcart -ms.date: 05/16/2016 -ms.topic: language-reference -ms.prod: .net -ms.technology: devlang-fsharp -ms.devlang: fsharp -ms.assetid: 81adb2eb-625f-4ad8-aeaa-8f672a6d79a2 ---- - -# Walkthrough: Generating F# Types from an EDMX Schema File - -> [!NOTE] -This guide was written for F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. - -> [!NOTE] -The API reference links will take you to MSDN. The docs.microsoft.com API reference is not complete. - -This walkthrough for F# 3.0 shows you how to create types for data that is represented by the Entity Data Model (EDM), the schema for which is specified in an .edmx file. This walkthrough also shows how to use the EdmxFile type provider. Before you begin, consider whether a SqlEntityConnection type provider is a more appropriate type provider option. The SqlEntityConnection type provider works best for scenarios where you have a live database that you can connect to during the development phase of your project, and you do not mind specifying the connection string at compile time. However, this type provider is also limited in that it doesn't expose as much database functionality as the EdmxFile type provider. Also, if you don't have a live database connection for a database project that uses the Entity Data Model, you can use the .edmx file to code against the database. When you use the EdmxFile type provider, the F# compiler runs EdmGen.exe to generate the types that it provides. - -This walkthrough illustrates the following tasks, which you must perform in this order for the walkthrough to succeed: - - -- Creating an EDMX file -
- -- Creating the project -
- -- Finding or creating the entity data model connection string -
- -- Configuring the type provider -
- -- Querying the data -
- -- Calling a stored procedure -
- - -## Prerequisites - -## Creating an EDMX file -If you already have an EDMX file, you can skip this step. - - -#### To create an EDMX file - -- If you don't already have an EDMX file, you can follow the instructions at the end of this walkthrough in the step [Configuring the Entity Data Model](generating-fsharp-types-from-edmx.md#configuring-the-entity-data-model). -
- -## Creating the project -In this step, you create a project and add appropriate references to it to use the EDMX type provider. - - -#### To create and set up an F# project - -1. Close the previous project, create another project, and name it SchoolEDM. -
- -2. In **Solution Explorer**, open the shortcut menu for **References**, and then choose **Add Reference**. -
- -3. In the **Assemblies** area, choose the **Framework** node. -
- -4. In the list of available assemblies, choose the **System.Data.Entity** and **System.Data.Linq** assemblies, and then choose the **Add** button to add references to these assemblies to your project. -
- -5. In the **Assemblies** area, select the **Extensions** node. -
- -6. In the list of available extensions, add a reference to the FSharp.Data.TypeProviders assembly. -
- -7. Add the following code to open the appropriate namespaces. -
- -```fsharp -open System.Data.Linq -open System.Data.Entity -open Microsoft.FSharp.Data.TypeProviders -``` - -## Finding or creating the connection string for the Entity Data Model -The connection string for the Entity Data Model (EDMX connection string) includes not only the connection string for the database provider but also additional information. For example, EDMX connection string for a simple SQL Server database resembles the following code. - -```fsharp -let edmConnectionString = "metadata=res://*/;provider=System.Data.SqlClient;Provider Connection String='Server=SERVER\Instance;Initial Catalog=DatabaseName;Integrated Security=SSPI;'" -``` - -For more information about EDMX connection strings, see [Connection Strings](../../../../docs/framework/data/adonet/connection-strings-and-configuration-files.md). - - -#### To find or create the connection string for the Entity Data Model - -1. EDMX connection strings can be difficult to generate by hand, so you can save time by generating it programmatically. If you know your EDMX connection string, you can bypass this step and simply use that string in the next step. If not, use the following code to generate the EDMX connection string from a database connection string that you provide. -
- -```fsharp -open System -open System.Data -open System.Data.SqlClient -open System.Data.EntityClient -open System.Data.Metadata.Edm - -let getEDMConnection(dbConnectionString) = - let dbConnection = new SqlConnection(dbConnectionString) - let resourceArray = [| "res://*/" |] - let assemblyList = [| System.Reflection.Assembly.GetCallingAssembly() |] - let metaData = MetadataWorkspace(resourceArray, assemblyList) - new EntityConnection(metaData, dbConnection) -``` - -## Configuring the type provider -In this step, you create and configure the type provider with the EDMX connection string, and you generate types for the schema that's defined in the .edmx file. - - -#### To configure the type provider and generate types - -1. Copy the .edmx file that you generated in the first step of this walkthrough to your project folder. -
- -2. Open the shortcut menu for the project node in your F# project, choose **Add Existing Item**, and then choose the .edmx file to add it to your project. -
- -3. Enter the following code to activate the type provider for your .edmx file. Replace *Server*\*Instance* with the name of your server that's running SQL Server and the name of your instance, and use the name of your .edmx file from the first step in this walkthrough. -
- -```fsharp -type edmx = EdmxFile<"Model1.edmx", ResolutionFolder = @""> - -use edmConnection = - getEDMConnection("Data Source=SERVER\instance;Initial Catalog=School;Integrated Security=true;") -use context = new edmx.SchoolModel.SchoolEntities(edmConnection) -``` - -## Querying the data -In this step, you use F# query expressions to query the database. - - -#### To query the data - -- Enter the following code to query the data in the entity data model. -
- -```fsharp -query { - for course in context.Courses do - select course -} |> Seq.iter (fun course -> printfn "%s" course.Title) - -query { - for person in context.Person do - select person -} |> Seq.iter (fun person -> printfn "%s %s" person.FirstName person.LastName) - -// Add a where clause to filter results -query { - for course in context.Courses do - where (course.DepartmentID = 1) - select course -} |> Seq.iter (fun course -> printfn "%s" course.Title) - -// Join two tables -query { - for course in context.Courses do - join dept in context.Departments on (course.DepartmentID = dept.DepartmentID) - select (course, dept.Name) -} |> Seq.iter (fun (course, deptName) -> printfn "%s %s" course.Title deptName) -``` - -## Calling a stored procedure -You can call stored procedures by using the EDMX type provider. In the following procedure, the School database contains a stored procedure, **UpdatePerson**, which updates a record, given new values for the columns. You can use this stored procedure because it's exposed as a method on the DataContext type. - - -#### To call a stored procedure - -- Add the following code to update records. -
- -```fsharp -// Call a stored procedure. -let nullable value = new System.Nullable<_>(value) - -// Assume now that you must correct someone's hire date. -// Throw an exception if more than one matching person is found. -let changeHireDate(lastName, firstName, hireDate) = - - query { - for person in context.People do - where (person.LastName = lastName && - person.FirstName = firstName) - exactlyOne - } |> (fun person -> - context.UpdatePerson(nullable person.PersonID, person.LastName, person.FirstName, nullable hireDate, person.EnrollmentDate)) - -changeHireDate("Abercrombie", "Kim", DateTime.Parse("1/12/1998")) -|> printfn "Result: %d" -``` - -The result is 1 if you succeed. Notice that **exactlyOne** is used in the query expression to ensure that only one result is returned; otherwise, an exception is thrown. Also, to work with nullable values more easily, you can use the simple **nullable** function that's defined in this code to create a nullable value out of an ordinary value. - -
- -## Configuring the Entity Data Model -You should complete this procedure only if you want to know how to generate a full Entity Data Model from a database and you don't have a database with which to test. - - -#### To configure the Entity Data Model - -1. On the menu bar, choose **SQL**, **Transact-SQL Editor**, **New Query** to create a database. If prompted, specify your database server and instance. -
- -2. Copy and paste the contents of the database script that creates the Student database, as described in the [Entity Framework documentation](https://msdn.microsoft.com/data/JJ614587.aspx) in the Data Developer Center. -
- -3. Run the SQL script by choosing the toolbar button with the triangle symbol or choosing the Ctrl+Q keys. -
- -4. In **Server Explorer**, open the shortcut menu for **Data Connections**, choose **Add Connection**, and then enter the name of the database server, the name of the instance name, and the School database. -
- -5. Create a C# or Visual Basic Console Application project, open its shortcut menu, choose **Add New Item**, and then choose **ADO.NET Entity Data Model**. -
The Entity Data Model Wizard opens. By using this wizard, you can choose how you want to create the Entity Data Model. -
- -6. Under **Choose Model Contents**, select the **Generate from database** check box. -
- -7. On the next page, choose your newly created School database as the data connection. -
This connection should resemble **<servername>.<instancename>.School.dbo**. -
- -8. Copy your entity connection string to the Clipboard because that string might be important later. -
- -9. Make sure the check box to save the entity connection string to the **App.Config** file is selected, and make note of the string value in the text box, which should help you locate the connection string later, if needed. -
- -10. On the next page, choose **Tables** and **Stored Procedures and Functions**. -
By choosing these top-level nodes, you choose all tables, stored procedures, and functions. You can also choose these individually, if you want. -
- -11. Make sure that the check boxes for the other settings are selected. -
The first **Pluralize or singularize generated object names** check box indicates whether to change singular forms to plural to match conventions in naming objects that represent database tables. The **Include foreign key columns in the model** check box determines whether to include fields for which the purpose is to join to other fields in the object types that are generated for the database schema. The third check box indicates whether to include stored procedures and functions in the model. -
- -12. Select the **Finish** button to generate an .edmx file that contains an Entity Data Model that's based on the School database. -
A file, **Model1.edmx**, is added to your project, and a database diagram appears. -
- -13. On the menu bar, choose **View**, **Other Windows**, **Entity Data Model Browser** to view all the details of the model or **Entity Data Model Mapping Details** to open a window that shows how the generated object model maps onto database tables and columns. -
- - -## Next Steps -Explore other queries by looking at the available query operators as listed in [Query Expressions](../../language-reference/query-expressions.md). - - -## See Also -[Type Providers](index.md) - -[EdmxFile Type Provider](https://msdn.microsoft.com/visualfsharpdocs/conceptual/edmxfile-type-provider-%5bfsharp%5d) - -[Walkthrough: Accessing a SQL Database by Using Type Providers and Entities](accessing-a-sql-database-entities.md) - -[Entity Framework](https://msdn.microsoft.com/data/ef) - -[.edmx File Overview](https://msdn.microsoft.com/library/f4c8e7ce-1db6-417e-9759-15f8b55155d4) - -[EDM Generator (EdmGen.exe)](https://msdn.microsoft.com/library/bb387165) - diff --git a/docs/fsharp/tutorials/type-providers/index.md b/docs/fsharp/tutorials/type-providers/index.md index f6a5d121e420a..a40f416746f0c 100644 --- a/docs/fsharp/tutorials/type-providers/index.md +++ b/docs/fsharp/tutorials/type-providers/index.md @@ -1,10 +1,9 @@ --- title: Type Providers description: Learn how an F# type provider is a component that provides types, properties, and methods for use in your programs. -keywords: visual f#, f#, functional programming author: cartermp ms.author: phcart -ms.date: 05/16/2016 +ms.date: 04/02/2018 ms.topic: language-reference ms.prod: .net ms.technology: devlang-fsharp @@ -14,36 +13,35 @@ ms.assetid: 25697ef6-465e-4248-9de5-1d199d4a8b59 # Type Providers -> [!NOTE] -This guide was written from F# 3.0 and will be updated. See [FSharp.Data](https://fsharp.github.io/FSharp.Data/) for up-to-date, cross-platform type providers. +An F# type provider is a component that provides types, properties, and methods for use in your program. Type Providers generate what are known as **Provided Types**, which are generated by the F# compiler and are based on an external data source. -An F# type provider is a component that provides types, properties, and methods for use in your program. Type providers are a significant part of F# 3.0 support for information-rich programming. The key to information-rich programming is to eliminate barriers to working with diverse information sources found on the Internet and in modern enterprise environments. One significant barrier to including a source of information into a program is the need to represent that information as types, properties, and methods for use in a programming language environment. Writing these types manually is very time-consuming and difficult to maintain. A common alternative is to use a code generator which adds files to your project; however, the conventional types of code generation do not integrate well into exploratory modes of programming supported by F# because the generated code must be replaced each time a service reference is adjusted. +For example, an F# Type Provider for SQL can generate types representing tables and columns in a relational database. In fact, this is what the [SQLProvider](https://fsprojects.github.io/SQLProvider/) Type Provider does. -The types provided by F# type providers are usually based on external information sources. For example, an F# type provider for SQL will provide the types, properties, and methods you need to work directly with the tables of any SQL database you have access to. Similarly, a type provider for WSDL web services will provide the types, properties, and methods you need to work directly with any WSDL web service. +Provided Types depend on input parameters to a Type Provider. Such input can be a sample data source (such as a JSON schema file), a URL pointing directly to an external service, or a connection string to a data source. A Type Provider can also ensure that groups of types are only expanded on demand; that is, they are expanded if the types are actually referenced by your program. This allows for the direct, on-demand integration of large-scale information spaces such as online data markets in a strongly typed way. -The set of types, properties, and methods provided by an F# type provider can depend on parameters given in program code. For example, a type provider can provide different types depending on a connection string or a service URL. In this way, the information space available by means of a connection string or URL is directly integrated into your program. A type provider can also ensure that groups of types are only expanded on demand; that is, they are expanded if the types are actually referenced by your program. This allows for the direct, on-demand integration of large-scale information spaces such as online data markets in a strongly typed way. +## Generative and Erased Type Providers -F# contains several built-in type providers for commonly used Internet and enterprise data services. These type providers give simple and regular access to SQL relational databases and network-based OData and WSDL services and support the use of F# LINQ queries against these data sources. +Type Providers come in two forms: Generative and Erased. -Where necessary, you can create your own custom type providers, or reference type providers that have been created by others. For example, assume your organization has a data service providing a large and growing number of named data sets, each with its own stable data schema. You may choose to create a type provider that reads the schemas and presents the latest available data sets to the programmer in a strongly typed way. +Generative Type Providers produce types that can be written as .NET types into the assembly in which they are produced. This allows them to be consumed from code in other assemblies. This means that the typed representation of the data source must generally be one that is feasible to represent with .NET types. +Erasing Type Providers produce types that can only be consumed in the assembly or project they are generated from. The types are ephemeral; that is, they are not written into an assembly and cannot be consumed by code in other assemblies. They can contain *delayed* members, allowing you to use provided types from a potentially infinite information space. They are useful for using a small subset of a large and interconnected data source. -## Related Topics +## Commonly used Type Providers +The following widely-used libraries contain Type Providers for different uses: -|Title|Description| -|-----|-----------| -|[Walkthrough: Accessing a SQL Database by Using Type Providers](accessing-a-sql-database.md)|Explains how to use the SqlDataConnection type provider to access the tables and stored procedures of a SQL database based on a connection string for a direct connection to a database. The access uses a LINQ to SQL mapping.| -|[Walkthrough: Accessing a SQL Database by Using Type Providers and Entities](accessing-a-sql-database-entities.md)|Explains how to use the SqlEntityConnection type provider to access the tables and stored procedures of a SQL database, based on a connection string for a direct connection to a database. The access uses a LINQ to Entities mapping. This method works with any database but the example demonstrated is SQL Server.| -|[Walkthrough: Accessing an OData Service by Using Type Providers](accessing-an-odata-service.md)|Explains how to use the ODataService type provider to access an OData service in a strongly typed way based on a service URL.| -|[Walkthrough: Accessing a Web Service by Using Type Providers](accessing-a-web-service.md)|Explains how to use the WsdlService type provider to access a WSDL web service in a strongly typed way based on a service URL.| -|[Walkthrough: Generating F# Types from a DBML File](generating-fsharp-types-from-dbml.md)|Explains how to use the DbmlFile type provider to access the tables and stored procedures of a SQLdatabase, based on a DBML file giving a Linq to SQL database schema specification.| -|[Walkthrough: Generating F# Types from an EDMX Schema File](generating-fsharp-types-from-edmx.md)|Explains how to use the EdmxFile type provider to access the tables and stored procedures of a SQL database, based on an EDMX file giving an Entity Framework schema specification.| -|[Tutorial: Creating a Type Provider](creating-a-type-provider.md)|Provides information on writing your own custom type providers.| -|[Type Provider Security](type-provider-security.md)|Provides information about security considerations when developing type providers.| -|[Troubleshooting Type Providers](troubleshooting-type-providers.md)|Provides information about common problems that can arise when working with type providers and includes suggestions for solutions.| +- [FSharp.Data](https://fsharp.github.io/FSharp.Data/) includes Type Providers for JSON, XML, CSV, and HTML document formats and resources. +- [SQLProvider](https://fsprojects.github.io/SQLProvider/) provides strongly-typed access to relation databases through object mapping and F# LINQ queries against these data sources. +- [FSharp.Data.SqlClient](https://fsprojects.github.io/FSharp.Data.SqlClient/) has a set of type providers for compile-time checked embedding of T-SQL in F#. +- [Azure Storage Type provider](https://fsprojects.github.io/AzureStorageTypeProvider/) provides types for Azure Blobs, Tables, and Queues, allowing you to access these resources without needing to specify resource names as strings throughout your program. +- [FSharp.Data.GraphQL](https://fsprojects.github.io/FSharp.Data.GraphQL/index.html) contains the **GraphQLProvider**, which provides types based on a GraphQL server specified by URL. + +Where necessary, you can [create your own custom type providers](creating-a-type-provider.md), or reference type providers that have been created by others. For example, assume your organization has a data service providing a large and growing number of named data sets, each with its own stable data schema. You may choose to create a type provider that reads the schemas and presents the latest available data sets to the programmer in a strongly typed way. ## See Also +[Tutorial: Create a Type Provider](creating-a-type-provider.md) + [F# Language Reference](../../language-reference/index.md) [Visual F#](../../index.md) diff --git a/docs/standard/async.md b/docs/standard/async.md index 0a139b4be9224..2d217f06f9383 100644 --- a/docs/standard/async.md +++ b/docs/standard/async.md @@ -37,4 +37,14 @@ Async code has the following characteristics: ## What's next? -For a deep dive into async concepts and programming, see [Async in depth](async-in-depth.md) and [Task-based asynchronous programming](~/docs/standard/parallel-programming/task-based-asynchronous-programming.md). +For more information, see the [Async in depth](async-in-depth.md) topic. + +The [Asynchronous Programming Patterns](/asynchronous-programming-patterns/index.md) topic provides an overview of the three asynchronous programming patterns supported in .NET: + +- [Asynchronous Programming Model (APM)](asynchronous-programming-patterns/asynchronous-programming-model-apm.md) (legacy) + +- [Event-based Asynchronous Pattern (EAP)](asynchronous-programming-patterns/event-based-asynchronous-pattern-eap.md) (legacy) + +- [Task-based Asynchronous Pattern (TAP)](asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md) (recommended for new development) + +For more information about recommended task-based programming model, see the [Task-based asynchronous programming](parallel-programming/task-based-asynchronous-programming.md) topic. diff --git a/docs/standard/parallel-processing-and-concurrency.md b/docs/standard/parallel-processing-and-concurrency.md index 36bec32266dc6..9e4ab4491ec02 100644 --- a/docs/standard/parallel-processing-and-concurrency.md +++ b/docs/standard/parallel-processing-and-concurrency.md @@ -1,18 +1,14 @@ --- -title: "Parallel Processing and Concurrency in the .NET Framework" -ms.custom: "" -ms.date: "03/30/2017" +title: "Parallel Processing, Concurrency, and Async Programming in .NET" +description: "Learn how to make your application more responsive and faster with .NET capabilities for parallel processing and asynchronous programming" +ms.date: "04/06/2018" ms.prod: ".net" -ms.reviewer: "" -ms.suite: "" ms.technology: dotnet-standard -ms.tgt_pltfrm: "" ms.topic: "article" helpviewer_keywords: - - ".NET Framework, parallel processing" - - "parallel processing [.NET Framework]" - - "concurrency [.NET Framework]" - - ".NET Framework, concurrency" + - "parallel processing [.NET]" + - "concurrency [.NET]" + - "asynchronous programming [.NET]" ms.assetid: e573faa8-0212-44b1-a850-ce85dc54f47f caps.latest.revision: 7 author: "rpetrusha" @@ -22,24 +18,15 @@ ms.workload: - "dotnet" - "dotnetcore" --- -# Parallel Processing and Concurrency in the .NET Framework -The .NET Framework provides several ways for you to use multiple threads of execution to keep your application responsive to your user while maximizing the performance of your user's computer. +# Parallel Processing, Concurrency, and Async Programming in .NET +.NET provides several ways for you to write asynchronous code to make your application more responsive to a user and write parallel code that uses multiple threads of execution to maximize the performance of your user's computer. ## In This Section - [Threading](../../docs/standard/threading/index.md) - Describes the basic concurrency and synchronization mechanisms provided by the .NET Framework. - - [Asynchronous Programming Patterns](../../docs/standard/asynchronous-programming-patterns/index.md) - Provides a brief overview of the three asynchronous programming patterns supported in the .NET Framework: - -- [Asynchronous Programming Model (APM)](../../docs/standard/asynchronous-programming-patterns/asynchronous-programming-model-apm.md) (legacy) - -- [Event-based Asynchronous Pattern (EAP)](../../docs/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-eap.md) (legacy) - -- [Task-based Asynchronous Pattern (TAP)](../../docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md) (recommended for new development) + [Asynchronous Programming](../../docs/standard/async.md) + Describes mechanisms for asynchronous programming provided by .NET. [Parallel Programming](../../docs/standard/parallel-programming/index.md) Describes a task-based programming model that simplifies parallel development, enabling you to write efficient, fine-grained, and scalable parallel code in a natural idiom without having to work directly with threads or the thread pool. - -## See Also - [Development Guide](../../docs/framework/development-guide.md) + + [Threading](../../docs/standard/threading/index.md) + Describes the basic concurrency and synchronization mechanisms provided by .NET. diff --git a/docs/standard/threading/index.md b/docs/standard/threading/index.md index 4bedbc840ac28..d20735f17dd35 100644 --- a/docs/standard/threading/index.md +++ b/docs/standard/threading/index.md @@ -56,8 +56,8 @@ Whether you are developing for computers with one processor or several, you want [Asynchronous File I/O](../../../docs/standard/io/asynchronous-file-i-o.md) Describes the performance advantages and basic operation of asynchronous I/O. - [Event-based Asynchronous Pattern (EAP)](../../../docs/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-eap.md) - Provides an overview of asynchronous programming. + [Task-based Asynchronous Pattern (TAP)](../../../docs/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap.md) + Provides an overview of the recommended pattern for asynchronous programming in .NET. [Calling Synchronous Methods Asynchronously](../../../docs/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously.md) Explains how to call methods on thread pool threads using built-in features of delegates. diff --git a/docs/toc.md b/docs/toc.md index b32402cd7d9b1..d7a64c6750e8c 100644 --- a/docs/toc.md +++ b/docs/toc.md @@ -35,9 +35,12 @@ ## [Delegates and lambdas](standard/delegates-lambdas.md) ## [LINQ](standard/using-linq.md) ## [Common Type System & Common Language Specification](standard/common-type-system.md) -## [Asynchronous programming](standard/async.md) -### [Asynchronous programming in depth](standard/async-in-depth.md) -### [Asynchronous Programming Patterns](standard/asynchronous-programming-patterns/) +## [Parallel Processing, Concurrency, and Async](standard/parallel-processing-and-concurrency.md) +### [Asynchronous programming](standard/async.md) +#### [Asynchronous programming in depth](standard/async-in-depth.md) +#### [Asynchronous Programming Patterns](standard/asynchronous-programming-patterns/) +### [Parallel Programming](standard/parallel-programming/) +### [Threading](standard/threading/) ## [Native interoperability](standard/native-interop.md) ## [Collections and Data Structures](standard/collections/) ## [Numerics in .NET](standard/numerics.md) @@ -46,15 +49,12 @@ ## [Managed Execution Process](standard/managed-execution-process.md) ## [Metadata and Self-Describing Components](standard/metadata-and-self-describing-components.md) ## [Building Console Applications](standard/building-console-apps.md) -## [Parallel Processing and Concurrency](standard/parallel-processing-and-concurrency.md) ## [Application Essentials](standard/application-essentials.md) ## [File and Stream I/O](standard/io/index.md) ## [Globalization and Localization](standard/globalization-localization/) ## [Attributes](standard/attributes/) ## [Framework Design Guidelines](standard/design-guidelines/) ## [XML Documents and Data](standard/data/xml/) -## [Threading](standard/threading/) -## [Parallel Programming](standard/parallel-programming/) ## [Security](standard/security/) ## [Serialization](standard/serialization/) ## [Developing for Multiple Platforms](standard/cross-platform/) @@ -226,7 +226,7 @@ ### [C# Type system](csharp/programming-guide/types/index.md) ### [Namespaces](csharp/programming-guide/namespaces/index.md) ### [Basic Types](csharp/basic-types.md) -### [Classes](csharp/classes.md) +### [Classes](csharp/programming-guide/classes-and-structs/classes.md) ### [Structs](csharp/structs.md) ### [Tuples](csharp/tuples.md) ### [Deconstructing tuples and other types](csharp/deconstruct.md) @@ -289,13 +289,7 @@ ## Tutorials ### [F# Interactive](fsharp/tutorials/fsharp-interactive/index.md) ### [Type Providers](fsharp/tutorials/type-providers/index.md) -#### [Accessing a SQL Database by Using Type Providers](fsharp/tutorials/type-providers/accessing-a-sql-database.md) -#### [Accessing a SQL Database by Using Type Providers and Entities](fsharp/tutorials/type-providers/accessing-a-sql-database-entities.md) -#### [Accessing an OData Service by Using Type Providers](fsharp/tutorials/type-providers/accessing-an-odata-service.md) -#### [Accessing a Web Service Using Type Providers](fsharp/tutorials/type-providers/accessing-a-web-service.md) -#### [Generating F# Types from a DBML File](fsharp/tutorials/type-providers/generating-fsharp-types-from-dbml.md) -#### [Generating F# Types from an EDMX File](fsharp/tutorials/type-providers/generating-fsharp-types-from-edmx.md) -#### [Creating a Type Provider](fsharp/tutorials/type-providers/creating-a-type-provider.md) +#### [Create a Type Provider](fsharp/tutorials/type-providers/creating-a-type-provider.md) #### [Type provider Security](fsharp/tutorials/type-providers/type-provider-security.md) #### [Troubleshooting Type Providers](fsharp/tutorials/type-providers/troubleshooting-type-providers.md)