├── .github
├── dependabot.yml
└── workflows
│ ├── build-documentation.yml
│ └── markdownlint-problem-matcher.json
├── .gitignore
├── .gitmodules
├── .markdownlint.json
├── .vscode
└── settings.json
├── CNAME
├── README.md
├── conceptual
├── EF6.PG
│ ├── index.md
│ └── toc.md
├── EFCore.PG
│ ├── index.md
│ ├── mapping
│ │ ├── array.md
│ │ ├── enum.md
│ │ ├── full-text-search.md
│ │ ├── general.md
│ │ ├── json.md
│ │ ├── nodatime.md
│ │ ├── nts.md
│ │ ├── range.md
│ │ └── translations.md
│ ├── misc
│ │ ├── collations-and-case-sensitivity.md
│ │ ├── database-creation.md
│ │ └── other.md
│ ├── modeling
│ │ ├── concurrency.md
│ │ ├── generated-properties.md
│ │ ├── indexes.md
│ │ └── tables.md
│ ├── release-notes
│ │ ├── 1.1.md
│ │ ├── 2.0.md
│ │ ├── 2.1.md
│ │ ├── 2.2.md
│ │ ├── 3.1.md
│ │ ├── 5.0.md
│ │ ├── 6.0.md
│ │ ├── 7.0.md
│ │ ├── 8.0.md
│ │ └── 9.0.md
│ └── toc.yml
└── Npgsql
│ ├── basic-usage.md
│ ├── compatibility.md
│ ├── connection-string-parameters.md
│ ├── contributing.md
│ ├── copy.md
│ ├── dev
│ ├── release-checklist.md
│ ├── tests.md
│ └── type-representations.md
│ ├── diagnostics
│ ├── exceptions_notices.md
│ ├── logging.md
│ ├── metrics.md
│ ├── overview.md
│ └── tracing.md
│ ├── failover-and-load-balancing.md
│ ├── faq.md
│ ├── index.md
│ ├── installation.md
│ ├── keepalive.md
│ ├── large-objects.md
│ ├── performance.md
│ ├── prepare.md
│ ├── release-notes
│ ├── 3.0.md
│ ├── 3.1.md
│ ├── 3.2.md
│ ├── 4.0.md
│ ├── 4.1.md
│ ├── 5.0.md
│ ├── 6.0.md
│ ├── 7.0.md
│ ├── 8.0.md
│ └── 9.0.md
│ ├── replication.md
│ ├── security.md
│ ├── toc.yml
│ ├── types
│ ├── basic.md
│ ├── datetime.md
│ ├── enums_and_composites.md
│ ├── geojson.md
│ ├── json.md
│ ├── nodatime.md
│ └── nts.md
│ └── wait.md
├── dev
├── build-server.md
├── index.md
├── tests.md
├── toc.md
└── types.md
├── docfx.json
├── favicons
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── browserconfig.xml
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── mstile-144x144.png
├── mstile-150x150.png
├── mstile-310x150.png
├── mstile-310x310.png
├── mstile-70x70.png
├── safari-pinned-tab.svg
└── site.webmanifest
├── img
├── jetbrains-logo.svg
├── logo.svg
├── postgresql.gif
├── warning.png
└── zipkin.png
├── index.md
└── toc.yml
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
--------------------------------------------------------------------------------
/.github/workflows/build-documentation.yml:
--------------------------------------------------------------------------------
1 | name: Build Documentation
2 |
3 | on:
4 | push:
5 | branches: [main]
6 |
7 | pull_request:
8 |
9 | # Used to trigger the flow from Npgsql/EFCore.PG via HTTP POST
10 | repository_dispatch:
11 |
12 | # Allows you to run this workflow manually from the Actions tab
13 | workflow_dispatch:
14 |
15 | concurrency:
16 | group: "pages"
17 | cancel-in-progress: false
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-22.04
22 |
23 | steps:
24 | - name: Checkout repo
25 | uses: actions/checkout@v4
26 |
27 | - name: Use Node.js
28 | uses: actions/setup-node@v4.4.0
29 | with:
30 | node-version: 20.x
31 |
32 | - name: Run Markdownlint
33 | run: |
34 | echo "::add-matcher::.github/workflows/markdownlint-problem-matcher.json"
35 | npm i -g markdownlint-cli
36 | markdownlint "conceptual/**/*.md"
37 |
38 | # Setup software
39 | - name: Setup .NET Core
40 | uses: actions/setup-dotnet@v4.3.1
41 | with:
42 | dotnet-version: 9.0.x
43 |
44 | - name: Checkout Npgsql
45 | uses: actions/checkout@v4
46 | with:
47 | repository: npgsql/npgsql
48 | ref: docs
49 | path: Npgsql
50 |
51 | # docfx has issues specifically with analyzer/sourcegen projects; build manually before.
52 | - name: Build Npgsql
53 | run: dotnet build -c Release
54 | shell: bash
55 | working-directory: Npgsql
56 |
57 | - name: Checkout EFCore.PG
58 | uses: actions/checkout@v4
59 | with:
60 | repository: npgsql/Npgsql.EntityFrameworkCore.PostgreSQL
61 | ref: docs
62 | path: EFCore.PG
63 |
64 | - name: Build EFCore.PG
65 | run: dotnet build -c Release
66 | shell: bash
67 | working-directory: EFCore.PG
68 |
69 | - name: Get docfx
70 | run: dotnet tool install --version 2.78.3 -g docfx
71 |
72 | - name: Build docs
73 | run: docfx --warningsAsErrors
74 |
75 | - name: Upload artifact
76 | uses: actions/upload-pages-artifact@v3
77 | with:
78 | path: _site
79 |
80 | deploy:
81 | needs: build
82 | runs-on: ubuntu-latest
83 | if: github.event_name == 'push' && github.ref_name == 'main'
84 | permissions:
85 | contents: read
86 | pages: write
87 | id-token: write
88 | environment:
89 | name: github-pages
90 | url: ${{ steps.deployment.outputs.page_url }}
91 | steps:
92 | - name: Deploy to GitHub Pages
93 | id: deployment
94 | uses: actions/deploy-pages@v4
95 |
--------------------------------------------------------------------------------
/.github/workflows/markdownlint-problem-matcher.json:
--------------------------------------------------------------------------------
1 | {
2 | "problemMatcher": [
3 | {
4 | "owner": "markdownlint",
5 | "pattern": [
6 | {
7 | "regexp": "^([^:]*):(\\d+):?(\\d+)?\\s([\\w-\\/]*)\\s(.*)$",
8 | "file": 1,
9 | "line": 2,
10 | "column": 3,
11 | "code": 4,
12 | "message": 5
13 | }
14 | ]
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | obj
2 | /EFCore.PG
3 | /Npgsql
4 | /_site
5 | /_exported_templates
6 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/npgsql/doc/4103e4fd1df97b6c01c5dfaa4b339d05fa69bf91/.gitmodules
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "default": true,
3 | "MD011": false,
4 | "MD013": false,
5 | "MD024": false,
6 | "MD028": false,
7 | "MD033": { "allowed_elements": ["del", "a", "sup"] },
8 | "MD051": false,
9 | "MD046": {
10 | "style": "fenced"
11 | },
12 | "MD055": false,
13 | "MD056": false
14 | }
15 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "Keepalive",
4 | "as",
5 | "citext",
6 | "concurrency",
7 | "daterange",
8 | "enum",
9 | "floatrange",
10 | "has",
11 | "has postgres enum",
12 | "hstore",
13 | "ilike",
14 | "inet",
15 | "jsonb",
16 | "jsonb typeof",
17 | "keepalives",
18 | "linq",
19 | "macaddr",
20 | "nextval",
21 | "noda",
22 | "noda time",
23 | "npgsql",
24 | "nuget",
25 | "numrange",
26 | "postgis",
27 | "postgres",
28 | "postgresql",
29 | "regconfig",
30 | "rowversion",
31 | "setweight",
32 | "tablespace",
33 | "tablespaces",
34 | "time",
35 | "timetz",
36 | "to",
37 | "to tsquery",
38 | "to tsvector",
39 | "token",
40 | "trunc",
41 | "tsquery",
42 | "tsrange",
43 | "tstzrange",
44 | "tsvector",
45 | "typeof",
46 | "use",
47 | "use xmin as concurrency token",
48 | "xmin"
49 | ]
50 | }
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | www.npgsql.org
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is the documentation repo for Npgsql.
2 |
3 | It contains conceptual documentation articles for Npgsql, Npgsql.EntityFrameworkCore.PostgreSQL (AKA EFCore.PG) and EntityFramework6.Npgsql (AKA EF6.PG).
4 |
5 | Note that to properly work, docfx expects to also find the Npgsql and EFCore.PG repos cloned in the repo root - it extracts API documentation from them.
6 |
7 | A Github Actions workflow automatically clones the appropriate repository, rebuilds the entire documentation and pushes the results to live.
8 |
--------------------------------------------------------------------------------
/conceptual/EF6.PG/index.md:
--------------------------------------------------------------------------------
1 | # Entity Framework 6
2 |
3 | Npgsql has an Entity Framework 6 provider. You can use it by installing the
4 | [EntityFramework6.Npgsql](https://www.nuget.org/packages/EntityFramework6.Npgsql/) nuget.
5 |
6 | ## Basic Configuration
7 |
8 | Configuration for an Entity Framework application can be specified in a config file (app.config/web.config) or through code. The latter is known as code-based configuration.
9 |
10 | ### Code-based
11 |
12 | To use Entity Framework with Npgsql, define a class that inherits from `DbConfiguration` in the same assembly as your class inheriting `DbContext`. Ensure that you configure provider services, a provider factory, a default connection factory as shown below:
13 |
14 | ```csharp
15 | using Npgsql;
16 | using System.Data.Entity;
17 |
18 | class NpgSqlConfiguration : DbConfiguration
19 | {
20 | public NpgSqlConfiguration()
21 | {
22 | var name = "Npgsql";
23 |
24 | SetProviderFactory(providerInvariantName: name,
25 | providerFactory: NpgsqlFactory.Instance);
26 |
27 | SetProviderServices(providerInvariantName: name,
28 | provider: NpgsqlServices.Instance);
29 |
30 | SetDefaultConnectionFactory(connectionFactory: new NpgsqlConnectionFactory());
31 | }
32 | }
33 | ```
34 |
35 | ### Config file
36 |
37 | When installing `EntityFramework6.Npgsql` nuget package, the relevant sections in `App.config` / `Web.config` are usually automatically updated. You typically only have to add your `connectionString` with the correct `providerName`.
38 |
39 | ```xml
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | ```
58 |
59 | ## Guid Support
60 |
61 | Npgsql EF migrations support uses `uuid_generate_v4()` function to generate guids.
62 | In order to have access to this function, you have to install the extension uuid-ossp through the following command:
63 |
64 | ```sql
65 | create extension "uuid-ossp";
66 | ```
67 |
68 | If you don't have this extension installed, when you run Npgsql migrations you will get the following error message:
69 |
70 | ```text
71 | ERROR: function uuid_generate_v4() does not exist
72 | ```
73 |
74 | If the database is being created by Npgsql Migrations, you will need to
75 | [run the `create extension` command in the `template1` database](http://stackoverflow.com/a/11584751).
76 | This way, when the new database is created, the extension will be installed already.
77 |
78 | ## Optimistic Concurrency
79 |
80 | EntityFramework supports [optimistic concurrency](https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application), through the [system column `xmin`](https://www.postgresql.org/docs/current/ddl-system-columns.html). To use this column as the concurrency token, some [customization is needed](https://github.com/npgsql/EntityFramework6.Npgsql/issues/8). The following code will setup `Department.Version` to map to `xmin`, while the `SqlGenerator` will generate `CREATE/ALTER TABLE` statements omitting system columns.
81 |
82 | ```csharp
83 | public class Department {
84 | public string Version { get; private set; }
85 | }
86 |
87 | [DbConfigurationType(typeof(Configuration))]
88 | public class UniversityDbContext : DbContext
89 | {
90 | public DbSet Departments { get; set; }
91 |
92 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
93 | {
94 | modelBuilder.Entity()
95 | .Property(p => p.Version)
96 | .HasColumnName("xmin")
97 | .HasColumnType("text")
98 | .IsConcurrencyToken()
99 | .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
100 | base.OnModelCreating(modelBuilder);
101 | }
102 | }
103 |
104 | internal class Configuration : DbConfiguration
105 | {
106 | public Configuration()
107 | {
108 | SetMigrationSqlGenerator("Npgsql", () => new SqlGenerator());
109 | }
110 | }
111 |
112 | public class SqlGenerator : NpgsqlMigrationSqlGenerator
113 | {
114 | private readonly string[] systemColumnNames = { "oid", "tableoid", "xmin", "cmin", "xmax", "cmax", "ctid" };
115 |
116 | protected override void Convert(CreateTableOperation createTableOperation)
117 | {
118 | var systemColumns = createTableOperation.Columns.Where(x => systemColumnNames.Contains(x.Name)).ToArray();
119 | foreach (var systemColumn in systemColumns)
120 | createTableOperation.Columns.Remove(systemColumn);
121 | base.Convert(createTableOperation);
122 | }
123 | }
124 | ```
125 |
126 | ## Template Database
127 |
128 | When the Entity Framework 6 provider creates a database, it issues a simple `CREATE DATABASE` command.
129 | In PostgreSQL, this implicitly uses `template1` as the template - anything existing in `template1` will
130 | be copied to your new database. If you wish to change the database used as a template, you can specify
131 | the `EF Template Database` connection string parameter. For more info see the
132 | [PostgreSQL docs](https://www.postgresql.org/docs/current/static/sql-createdatabase.html).
133 |
134 | ## Customizing DataReader Behavior
135 |
136 | You can use [an Entity Framework 6 IDbCommandInterceptor](https://msdn.microsoft.com/library/dn469464(v=vs.113).aspx) to wrap the `DataReader` instance returned by Npgsql when Entity Framework executes queries. This is possible using a ```DbConfiguration``` class.
137 |
138 | Example use cases:
139 |
140 | - Forcing all returned ```DateTime``` and ```DateTimeOffset``` values to be in the UTC timezone.
141 | - Preventing accidental insertion of DateTime values having ```DateTimeKind.Unspecified```.
142 | - Forcing all postgres date/time types to be returned to Entity Framework as ```DateTimeOffset```.
143 |
144 | ```csharp
145 | [DbConfigurationType(typeof(AppDbContextConfiguration))]
146 | public class AppDbContext : DbContext
147 | {
148 | // ...
149 | }
150 |
151 | public class AppDbContextConfiguration : DbConfiguration
152 | {
153 | public AppDbContextConfiguration()
154 | {
155 | this.AddInterceptor(new MyEntityFrameworkInterceptor());
156 | }
157 | }
158 |
159 | class MyEntityFrameworkInterceptor : DbCommandInterceptor
160 | {
161 | public override void ReaderExecuted(
162 | DbCommand command,
163 | DbCommandInterceptionContext interceptionContext)
164 | {
165 | if (interceptionContext.Result == null) return;
166 | interceptionContext.Result = new WrappingDbDataReader(interceptionContext.Result);
167 | }
168 |
169 | public override void ScalarExecuted(
170 | DbCommand command,
171 | DbCommandInterceptionContext