dotConnect for PostgreSQL Documentation
In This Topic
    Entity Framework Core Code-First Tutorial for Full .NET Framework
    In This Topic

    This tutorial guides you through the process of creating a simple application powered by Entity Framework Core. This application will create tables in the database based on the model in run-time, fill them with sample data, and execute queries.

    This tutorial is for Full .NET Framework. For .NET Core see Entity Framework Core Code-First Tutorial for .NET Core.

    Requirements

    If you want to target Entity Framework Core 3.1, this tutorial requires the following:

    If you want to target Entity Framework Core 2.2, this tutorial requires the following:

    If you want to target Entity Framework Core 1.1, this tutorial requires the following:

    Note that Entity Framework support is available only in Professional Edition of dotConnect for PostgreSQL.

    Creating Application

    To create the sample application, let's perform the following steps:
    1. Create a new console application.
    2. For Entity Framework Core 2.2 or 3.1, ensure that you are targeting .NET Framework 4.6.1 or later. For Entity Framework Core 1.1, ensure that you are targeting .NET Framework 4.5.1 or later.
    3. Install the Entity Framework Core NuGet package by executing the following command in the Package Manager Console (for Entity Framework Core 3.1):
      Install-Package Microsoft.EntityFrameworkCore.Relational 


      For Entity Framework Core 2.2, the command will be the following:
      Install-Package Microsoft.EntityFrameworkCore.Relational -Version 2.2.6
    4. For Entity Framework Core 1.1, the command will be the following:
      Install-Package Microsoft.EntityFrameworkCore.Relational -Version 1.1.4
    5. Additionally you need to add references to the following assemblies to your project:

      • Devart.Data.dll
      • Devart.Data.PostgreSql.dll
      • Devart.Data.PostgreSql.Entity.EFCore.dll

      Please note that there are two versions of Devart.Data.PostgreSql.Entity.EFCore.dll assemblies - for Entity Framework Core 2.0 and for Entity Framework Core 1.1. The first is located in the \Entity\EFCore2 subfolder of the dotConnect for PostgreSQL installation folder, and the second one - in the \Entity\EFCore subfolder.

    6. Create a DbContext descendant.
      using Microsoft.EntityFrameworkCore;
      using System;
      using System.Collections.Generic;
      using System.ComponentModel.DataAnnotations;
      using System.ComponentModel.DataAnnotations.Schema;
      using System.Data;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
       
      public class MyDbContext : DbContext {
       
      }
      Imports Microsoft.EntityFrameworkCore
      Imports System.Collections.Generic
      Imports System.ComponentModel.DataAnnotations
      Imports System.ComponentModel.DataAnnotations.Schema
      Imports System.Data
      Imports System.IO
      Imports System.Linq
      Imports System.Text
      Imports System.Threading.Tasks
      
      Public Class MyDbContext
      	Inherits DbContext
      
      End Class
      
    7. Register Entity Framework Core provider for using with our DbContext and specify the connection string. For this override the OnConfiguring method.
      public class MyDbContext : DbContext {
       
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
      
           optionsBuilder.UsePostgreSql(@"host=server;database=test;user id=postgres;");
        } 
      }
      Public Class MyDbContext
      	Inherits DbContext
      
      	Protected Overrides Sub OnConfiguring(optionsBuilder As DbContextOptionsBuilder)
      
      		optionsBuilder.UsePostgreSql("host=server;database=test;user id=postgres;")
      	End Sub
      End Class
      
    8. Create entity classes, used in the model. If necessary, set DataAnnotation attributes for the classes and properties.

      + Show/Hide code

    9. Add our classes to the DbContext descendant as DbSet properties. If necessary, you can also write fluent mapping, by overriding the OnModelCreating method.
      public class MyDbContext : DbContext {
       
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
       
          optionsBuilder.UsePostgreSql(@"host=server;database=test;user id=postgres;");
        }
       
        protected override void OnModelCreating(ModelBuilder modelBuilder) {
       
          modelBuilder.Entity<OrderDetail>()
            .HasKey(p => new { p.OrderID, p.ProductID });
        } 
        
        public DbSet<Product> Products { get; set; }
        public DbSet<ProductCategory> ProductCategories { get; set; }
        public DbSet<OrderDetail> OrderDetails { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<Company> Companies { get; set; }
        public DbSet<PersonContact> PersonContacts { get; set; }
      }
      
      Public Class MyDbContext
      	Inherits DbContext
      
      	Protected Overrides Sub OnConfiguring(optionsBuilder As DbContextOptionsBuilder)
      
      		optionsBuilder.UsePostgreSql("host=server;database=test;user id=postgres;")
      	End Sub
      
      	Protected Overrides Sub OnModelCreating(modelBuilder As ModelBuilder)
      
      		modelBuilder.Entity(Of OrderDetail)().HasKey(Function(p) New From { _
      			p.OrderID, _
      			p.ProductID _
      		})
      	End Sub
      
      	Public Property Products() As DbSet(Of Product)
      		Get
      			Return m_Products
      		End Get
      		Set
      			m_Products = Value
      		End Set
      	End Property
      	Private m_Products As DbSet(Of Product)
      	Public Property ProductCategories() As DbSet(Of ProductCategory)
      		Get
      			Return m_ProductCategories
      		End Get
      		Set
      			m_ProductCategories = Value
      		End Set
      	End Property
      	Private m_ProductCategories As DbSet(Of ProductCategory)
      	Public Property OrderDetails() As DbSet(Of OrderDetail)
      		Get
      			Return m_OrderDetails
      		End Get
      		Set
      			m_OrderDetails = Value
      		End Set
      	End Property
      	Private m_OrderDetails As DbSet(Of OrderDetail)
      	Public Property Orders() As DbSet(Of Order)
      		Get
      			Return m_Orders
      		End Get
      		Set
      			m_Orders = Value
      		End Set
      	End Property
      	Private m_Orders As DbSet(Of Order)
      	Public Property Companies() As DbSet(Of Company)
      		Get
      			Return m_Companies
      		End Get
      		Set
      			m_Companies = Value
      		End Set
      	End Property
      	Private m_Companies As DbSet(Of Company)
      	Public Property PersonContacts() As DbSet(Of PersonContact)
      		Get
      			Return m_PersonContacts
      		End Get
      		Set
      			m_PersonContacts = Value
      		End Set
      	End Property
      	Private m_PersonContacts As DbSet(Of PersonContact)
      End Class
      
      

    10. Now let's choose how to create the database. We can generate Code-First Migrations. Or, for test purposes, we can implement the analogue of Entity Framework 6 initialization strategy DropCreateDatabaseAlways.

      + Show/Hide code

    11. Now let's add code that creates the context, re-creates the database, fills it with the test data, and executes LINQ to Entities queries. Before compiling the following code add the Microsoft.EntityFrameworkCore namespace to the using list (for C#) or to the Imports list (for VB).
        class Program {
       
          static void Main(string[] args) {
       
            var context = new MyDbContext ();
       
            Console.WriteLine("Entity Framework Core Code-First sample");
            Console.WriteLine();
       
            MyDbContextSeeder.Seed(context);
       
            Console.WriteLine("Products with categories");
            Console.WriteLine();
       
            var query = context.Products.Include(p => p.Category)
                .Where(p => p.Price > 20.0)
                .ToList();
       
            Console.WriteLine("{0,-10} | {1,-50} | {2}", "ProductID", "ProductName", "CategoryName");
            Console.WriteLine();
            foreach (var product in query )
              Console.WriteLine("{0,-10} | {1,-50} | {2}", product.ProductID, product.ProductName, product.Category.CategoryName);
       
            Console.ReadKey();
          }
        }
      
      Class Program
      
      	Private Shared Sub Main(args As String())
      
      		Dim context = New MyDbContext()
      
      		Console.WriteLine("Entity Framework Core Code-First sample")
      		Console.WriteLine()
      
      		MyDbContextSeeder.Seed(context)
      
      		Console.WriteLine("Products with categories")
      		Console.WriteLine()
      
      		Dim query = context.Products.Include(Function(p) p.Category).Where(Function(p) p.Price > 20.0).ToList()
      
      		Console.WriteLine("{0,-10} | {1,-50} | {2}", "ProductID", "ProductName", "CategoryName")
      		Console.WriteLine()
      		For Each product As var In query
      			Console.WriteLine("{0,-10} | {1,-50} | {2}", product.ProductID, product.ProductName, product.Category.CategoryName)
      		Next
      
      		Console.ReadKey()
      	End Sub
      End Class
      
      

    12. Now we can run the application. It will create tables in the database, fill them with data, execute a query and output its results to the console:
      Entity Framework Core Code-First sample
      
      Products with categories
      
      ProductID  | ProductName                                        | CategoryName
      
      1          | Harrison G. B. England in Shakespeare's day        | novel
      2          | Twain Mark. Ventures of Huckleberry Finn           | novel
      3          | Plutarchus. Plutarch's moralia                     | prose
      4          | Shakespeare W. Shakespeare's dramatische Werke     | prose
      5          | King Stephen. 'Salem's Lot                         | poetry

    See Also

    Entity Framework section  | Entity Framework Support Overview