-
Notifications
You must be signed in to change notification settings - Fork 229
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
132 changed files
with
7,254 additions
and
1,398 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# Getting Started | ||
|
||
Npgsql has an Entity Framework Core provider. It mostly behaves like a any other EFCore provider (e.g. SQL Server) - all the information in the [general EF Core docs](https://docs.microsoft.com/en-us/ef/core/index) applies. If you're just getting started with EF Core, those docs are the best place to start. | ||
|
||
Development happens in the [Npgsql.EntityFrameworkCore.PostgreSQL](https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL) repository, all issues should be reported there. | ||
|
||
## Using the Npgsql EF Core Provider | ||
|
||
To use the Npgsql EF Core provider, simply add a dependency on `Npgsql.EntityFrameworkCore.PostgreSQL`. You can follow the instructions in the general [EF Core Getting Started docs](https://docs.microsoft.com/en-us/ef/core/get-started/). | ||
|
||
Following is an example project.json using Npgsql EF Core: | ||
|
||
```json | ||
{ | ||
"version": "1.0.0-*", | ||
"buildOptions": { | ||
"debugType": "portable", | ||
"emitEntryPoint": true | ||
}, | ||
"dependencies": { | ||
"Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.2", | ||
"Microsoft.EntityFrameworkCore.Design": { | ||
"version": "1.0.0-preview2-final", | ||
"type": "build" | ||
} | ||
}, | ||
"frameworks": { | ||
"netcoreapp1.0": { | ||
"dependencies": { | ||
"Microsoft.NETCore.App": { | ||
"type": "platform", | ||
"version": "1.0.1" | ||
} | ||
}, | ||
"imports": "dnxcore50" | ||
} | ||
}, | ||
"tools": { | ||
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final" | ||
} | ||
} | ||
``` | ||
|
||
## Using an Existing Database (Database-First) | ||
|
||
The Npgsql EF Core provider also supports reverse-engineering a code model from an existing PostgreSQL database ("database-first"). To do so, add a dependency on Npgsql.EntityFrameworkCore.PostgreSQL.Design. Then, execute the following if you're using dotnet cli: | ||
|
||
```bash | ||
Scaffold-DbContext "Host=localhost;Database=mydatabase;Username=myuser;Password=mypassword" Npgsql.EntityFrameworkCore.PostgreSQL | ||
``` | ||
|
||
Or with Powershell: | ||
|
||
```powershell | ||
Scaffold-DbContext "Host=localhost;Database=mydatabase;Username=myuser;Password=mypassword" Npgsql.EntityFrameworkCore.PostgreSQL | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
## Type Mapping | ||
|
||
The EF Core provider can transparently map any type supported by Npgsql at the ADO.NET level. This means you can use PostgreSQL-specific types, such as `inet` or `circle`, directly in your entities - this wasn't possible in EF 6.x. Simply define your properties just as if they were a simple type, such as a string: | ||
|
||
```c# | ||
public class MyEntity | ||
{ | ||
public int Id { get; set; } | ||
public string Name { get; set; } | ||
public IPAddress IPAddress { get; set; } | ||
public NpgsqlCircle Circle { get; set; } | ||
public int[] SomeInts { get; set; } | ||
} | ||
``` | ||
|
||
Note that mapping array properties to [PostgreSQL arrays](https://www.postgresql.org/docs/current/static/arrays.html) is supported. However, operations such as indexing the array, searching for elements in it, etc. aren't yet translated to SQL and will be evaluated client-side. This will probably be fixed in 1.2. | ||
|
||
[PostgreSQL composite types](https://www.postgresql.org/docs/current/static/rowtypes.html), while supported at the ADO.NET level, aren't yet supported in the EF Core provider. This is tracked by [#22](https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/22). | ||
|
||
## Explicitly Specifying Datatypes (e.g. JSON) | ||
|
||
In some cases, your .NET property type can be mapped to several PostgreSQL datatypes; a good example is a string, which will be mapped to `text` by default, but can also be mapped to `jsonb`. You can explicitly specify the PostgreSQL datatype by adding the following to your model's `OnModelCreating`: | ||
|
||
```c# | ||
builder.Entity<Blog>() | ||
.Property(b => b.SomeStringProperty) | ||
.HasColumnType("jsonb"); | ||
``` | ||
|
||
Or, if you prefer annotations, use the `[Column]` attribute: | ||
|
||
```c# | ||
[Column(TypeName="jsonb")] | ||
public string SomeStringProperty { get; set; } | ||
``` | ||
|
||
## Translating Regular Expressions | ||
|
||
PostgreSQL supports [regular expression operations in the database](http://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP), and the Npgsql EF Core provider provides some support for evaluating C# regex operations at the backend. All you have to do is use `Regex.IsMatch` in your where clause: | ||
|
||
```c# | ||
var customersStartingWithA = context.Customers.Where(c => Regex.IsMatch(c.CompanyName, "^A")); | ||
``` | ||
|
||
Since this regular expression is evaluated at the server, the EF Core provider doesn't need to load all the customers from the database, saving lots of transfer bandwidth. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Migrating to 1.1 (in preview) | ||
|
||
Version 1.1.0-preview1 of the Npgsql Entity Framework Core provider has been released and is available on nuget. This version works with the [recently released 1.1.0-preview1 of Entity Framework Core](https://blogs.msdn.microsoft.com/dotnet/2016/10/25/announcing-entity-framework-core-1-1-preview-1/), and contains some new Npgsql features as well. Note that if you're using the command-line tools, you'll have to modify your tools section as described in the EF Core release post: | ||
|
||
```json | ||
"tools": { | ||
"Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final" | ||
}, | ||
``` | ||
|
||
## New Features | ||
|
||
Aside from general EF Core features, version 1.1.0 of the Npgsql provider contains the following: | ||
|
||
* Hilo key generation ([#5](https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/5)). This can be a much more efficient way to generate autoincrement key values. | ||
* PostgreSQL array mapping ([#15](https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/15)). This allows you to have plain CLR arrays on your entities, and have those arrays mapped to native [PostgreSQL array columns](https://www.postgresql.org/docs/current/static/arrays.html). | ||
* Optimistic concurrency with PostgreSQL's xmin column ([#19](https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/19)). Simply specify `.UseXminAsConcurrencyToken()` on an entity to start using this, see the [EF docs for more details](https://docs.efproject.net/en/latest/modeling/concurrency.html). | ||
* Cleanup of how serial (autoincrement) and generated GUID/UUID columns are managed. | ||
|
||
Here's the [full list of issues](https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/milestone/3?closed=1). Please report any problems to https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL. | ||
|
||
## Upgrading from 1.0.x | ||
|
||
If you've used 1.0.x without migrations, you can simply upgrade and everything should just work. Unfortunately, if you already have migrations from 1.0.x you'll have to do some manual fixups because of some bad decisions that were previously made. If deleting your old migrations and starting over (e.g. non-production database) is an option you may wish to do so. The following are instructions for fixing up 1.0.x migrations. | ||
|
||
First, Npgsql 1.0.x used a problematic method to identify serial (autoincrement) columns in migrations. If you look at your migration code you'll see `.Annotation("Npgsql:ValueGeneratedOnAdd", true)` on various columns. Unfortunately this annotation is also present non-serial columns, e.g. columns with default values. This causes various issues and has been replaced in 1.1. However, you'll have to remove `.Annotation("Npgsql:ValueGeneratedOnAdd", true)`, and replacing it with `.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)` but *only* on columns which should be serial (e.g. not on columns with defaults). If you attempt to run a migration that has the old annotation, Npgsql will throw an exception and refuse to run your migrations. | ||
|
||
Unfortunately, this change will cause some incorrect changes the first time you add a migration after the upgrade. To avoid this, simply add a dummy migration right after upgrading to 1.1 and then delete the two new migration files, but keeping the changes made to your ModelSnapshot.cs. From this point on everything should be fine. *Make sure you have no pending changes to your model before doing this!*. | ||
|
||
Apologies for this problematic upgrade procedure, it should at least keep things clean going forward. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Misc | ||
|
||
## Setting up PostgreSQL extensions | ||
|
||
The provider allows you to specify PostgreSQL extensions that should be set up in your database. | ||
Simply use HasPostgresExtension in your context's OnModelCreating: | ||
|
||
```c# | ||
protected override void OnModelCreating(ModelBuilder modelBuilder) { | ||
modelBuilder.HasPostgresExtension("hstore"); | ||
} | ||
``` | ||
|
||
## Optimistic Concurrency and Concurrency Tokens | ||
|
||
Entity Framework supports the concept of optimistic concurrency - a property on your entity is designated as a concurrency token, and EF detects concurrent modifications by checking whether that token has changed since the entity was read. You can read more about this in the [EF docs](https://docs.microsoft.com/en-us/ef/core/modeling/concurrency). | ||
|
||
Although applications can update concurrency tokens themselves, we frequently rely on the database automatically updating a column on update - a "last modified" timestamp, an SQL Server `rowversion`, etc. Unfortunately PostgreSQL doesn't have such auto-updating columns - but there is one feature that can be used for concurrency token. All PostgreSQL have a set of [implicit and hidden system columns](https://www.postgresql.org/docs/current/static/ddl-system-columns.htm://www.postgresql.org/docs/current/static/ddl-system-columns.html), among which `xmin` holds the ID of the latest updating transaction. Since this value automatically gets updated every time the row is changed, it is ideal for use as a concurrency token. | ||
|
||
To enable this feature on an entity, insert the following code into your models' `OnModelCreating` method: | ||
|
||
```c# | ||
modelBuilder.Entity<MyEntity>().ForNpgsqlUseXminAsConcurrencyToken(); | ||
``` | ||
|
||
## Using a database template | ||
|
||
When creating a new database, | ||
[PostgreSQL allows specifying another "template database"](http://www.postgresql.org/docs/current/static/manage-ag-templatedbs.html) | ||
which will be copied as the basis for the new one. This can be useful for including database entities which aren't managed by Entity Framework. You can trigger this by using HasDatabaseTemplate in your context's `OnModelCreating`: | ||
|
||
```c# | ||
modelBuilder.HasDatabaseTemplate("my_template_db"); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# [Getting Started](index.md) | ||
# Migration Notes | ||
## [From 1.0.x to 1.1.x](migration/1.1.md) | ||
# [Value Generation](value-generation.md) | ||
# [Mapping and Translation](mapping-and-translation.md) | ||
# [Miscellaneous](misc.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Value Generation | ||
|
||
See [the general EF Docs on value generation](https://docs.microsoft.com/en-us/ef/core/modeling/generated-properties) to better understand the concepts described here. | ||
|
||
## Serial (Autoincrement) Columns | ||
|
||
In PostgreSQL, the standard autoincrement column type is called `serial`. This isn't really a special type like in some other databases (e.g. SQL Server's IDENTITY), but rather a shorthand for specifying that the column's default value should come from a sequence. See [the PostgreSQL docs](https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL) for more info. | ||
|
||
When `ValueGeneratedOnAdd` is specified on a short, int or long property, the Npgsql EF Core provider will automatically map it to a `serial` column. Note that EF Core will automatically recognize key properties by convention (e.g. a property called `Id` in your entity) and will implicitly set them to `ValueGeneratedOnAdd`. | ||
|
||
Note that there was a significant and breaking change in 1.1. If you have existing migrations generated with 1.0, please read the [migration notes](migration/1.1.md). | ||
|
||
## HiLo Autoincrement Generation | ||
|
||
One disadvantage of database-generated values is that these values must be read back from the database after a row is inserted. If you're saving multiple related entities, this means you must perform multiple roundtrips as the first entity's generated key must be read before writing the second one. One solution to this problem is HiLo value generation: rather than relying on the database to generate each and every value, the application "allocates" a range of values, which it can then populate directly on new entities without any additional roundtrips. When the range is exhausted, a new range is allocated. In practical terms, this uses a sequence that increments by some large value (100 by default), allowing the application to insert 100 rows autonomously. | ||
|
||
To use HiLo, specify `ForNpgsqlUseSequenceHiLo` on a property in your model's `OnModelCreating`: | ||
|
||
```c# | ||
modelBuilder.Entity<Blog>().Property(b => b.Id).ForNpgsqlUseSequenceHiLo(); | ||
``` | ||
|
||
You can also make your model use HiLo everywhere: | ||
|
||
```c# | ||
modelBuilder.ForNpgsqlUseSequenceHiLo(); | ||
``` | ||
|
||
## Guid/UUID Generation | ||
|
||
By default, if you specify `ValueGeneratedOnAdd` on a Guid property, a random Guid value will be generated client-side and sent to the database. | ||
|
||
If you prefer to generate values in the database instead, you can do so by specifying `HasDefaultValueSql` on your property. Note that PostgreSQL doesn't include any Guid/UUID generation functions, you must add an extension such as `uuid-ossp` or `pgcrypto`. This can be done by placing the following code in your model's `OnModelCreating`: | ||
|
||
```c# | ||
modelBuilder.HasPostgresExtension("uuid-ossp"); | ||
modelBuilder | ||
.Entity<Blog>() | ||
.Property(e => e.SomeGuidProperty) | ||
.HasDefaultValueSql("uuid_generate_v4()"); | ||
``` | ||
|
||
See [the PostgreSQL docs on UUID for more details](https://www.postgresql.org/docs/current/static/datatype-uuid.html). | ||
|
||
## Computed Columns (On Add or Update) | ||
|
||
PostgreSQL does not support computed columns. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
{ | ||
"projects": [ "src", "test" ] | ||
"projects": [ "src", "test" ], | ||
"sdk": { | ||
"version": "1.0.0-preview2-003131" | ||
} | ||
} |
Oops, something went wrong.