Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conceptual/EFCore.PG/mapping/array.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ array.Take(2) | [array\[,2\]](https://www.postgr
array.Skip(1).Take(2) | [array\[2,3\]](https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING) | Added in 8.0
array1 == array2 | [array1 = array2](https://www.postgresql.org/docs/current/static/arrays.html) |
array1.SequenceEqual(array2) | [array1 = array2](https://www.postgresql.org/docs/current/static/arrays.html) |
array1.Take(2).SequenceEqual(array2) | [array1\[:2\] = array2](https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING) | Added in 11.0; also supports Skip() and Skip().Take()
arrayNonColumn.Contains(element) | [element = ANY(arrayNonColumn)](https://www.postgresql.org/docs/current/static/functions-comparisons.html#AEN21104) | Can use regular index
arrayColumn.Contains(element) | [arrayColumn @> ARRAY\[element\]](https://www.postgresql.org/docs/current/functions-array.html#ARRAY-OPERATORS-TABLE) | Can use GIN index
array.Append(element) | [array_append(array, element)](https://www.postgresql.org/docs/current/functions-array.html#ARRAY-FUNCTIONS-TABLE) | Added in 6.0
Expand Down
8 changes: 4 additions & 4 deletions conceptual/EFCore.PG/mapping/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ customer.RootElement.GetProperty("Orders").GetArrayLength()
EF.Functions.JsonContains(customer, @"{""Name"": ""Joe"", ""Age"": 25}")<sup>1</sup> | [customer @> '{"Name": "Joe", "Age": 25}'](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonContained(@"{""Name"": ""Joe"", ""Age"": 25}", customer)<sup>1</sup> | ['{"Name": "Joe", "Age": 25}' <@ customer](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExists(customer, "Age") | [customer ? 'Age'](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistsAny(customer, "Age", "Address") | [customer ?\| ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistsAll(customer, "Age", "Address") | [customer ?& ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistAny(customer, "Age", "Address") | [customer ?\| ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistAll(customer, "Age", "Address") | [customer ?& ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonTypeof(customer.GetProperty("Age")) == "number" | [jsonb_typeof(customer->'Age') = 'number'](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE)

### [Legacy POCO Mapping](#tab/poco)
Expand All @@ -274,8 +274,8 @@ customer.Orders.Length (or Count)
EF.Functions.JsonContains(customer, @"{""Name"": ""Joe"", ""Age"": 25}")<sup>1</sup> | [customer @> '{"Name": "Joe", "Age": 25}'](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonContained(@"{""Name"": ""Joe"", ""Age"": 25}", e.Customer)<sup>1</sup> | ['{"Name": "Joe", "Age": 25}' <@ customer](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExists(e.Customer, "Age") | [customer ? 'Age'](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistsAny(e.Customer, "Age", "Address") | [customer ?\| ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistsAll(e.Customer, "Age", "Address") | [customer ?& ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistAny(e.Customer, "Age", "Address") | [customer ?\| ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonExistAll(e.Customer, "Age", "Address") | [customer ?& ARRAY\['Age','Address'\]](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE)
EF.Functions.JsonTypeof(e.Customer.Age) | [jsonb_typeof(customer->'Age')](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE)

***
Expand Down
4 changes: 4 additions & 0 deletions conceptual/EFCore.PG/mapping/nodatime.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,13 @@ var oldEvents = context.Events.Where(p => p.SomeDate.Year < 2000);

Following is the list of supported NodaTime translations; If an operation you need is missing, please open an issue to request for it.

Starting with version 11.0, `EF.Functions.DateTrunc()` supports `LocalDateTime`, `Instant`, `ZonedDateTime`, `Period` and `Duration`. Its optional time zone argument is only supported for `Instant` and `ZonedDateTime` mapped to `timestamp with time zone`; without that argument, PostgreSQL uses the session time zone for these values.

.NET | SQL | Notes
-------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -----------
SystemClock.Instance.GetCurrentInstant() | [now()](https://www.postgresql.org/docs/current/functions-datetime.html) |
EF.Functions.DateTrunc("month", value) | [date_trunc('month', value)](https://www.postgresql.org/docs/current/functions-datetime.html) | Added in 11.0
EF.Functions.DateTrunc("month", instant, "Europe/Berlin") | [date_trunc('month', instant, 'Europe/Berlin')](https://www.postgresql.org/docs/current/functions-datetime.html) | Added in 11.0
LocalDateTime.Date | [date_trunc('day', timestamp)](https://www.postgresql.org/docs/current/functions-datetime.html) |
LocalDateTime.Second (also LocalTime, ZonedDateTime) | [date_part('second', timestamp)::INT](https://www.postgresql.org/docs/current/functions-datetime.html) |
LocalDateTime.Minute (also LocalTime, ZonedDateTime) | [date_part('minute', timestamp)::INT](https://www.postgresql.org/docs/current/functions-datetime.html) |
Expand Down
50 changes: 39 additions & 11 deletions conceptual/EFCore.PG/mapping/translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ string.Concat(str0, str1) | str0 \|\| str1
string.IsNullOrEmpty(value) | value IS NULL OR value = ''
string.IsNullOrWhiteSpace(value) | value IS NULL OR btrim(value, E' \t\n\r') = ''
stringValue.CompareTo(strB) | CASE WHEN stringValue = strB THEN 0 ... END
stringValue.Contains(value) | stringValue LIKE %value%
stringValue.EndsWith(value) | stringValue LIKE '%' \|\| value
stringValue.Contains(value) | stringValue LIKE %value% | char overload added in 11.0
stringValue.EndsWith(value) | stringValue LIKE '%' \|\| value | char overload added in 11.0
stringValue.FirstOrDefault() | substr(stringValue, 1, 1)
stringValue.IndexOf(value) | strpos(stringValue, value) - 1
stringValue.IndexOf(value) | strpos(stringValue, value) - 1 | char overload added in 11.0
stringValue.LastOrDefault() | substr(stringValue, length(stringValue), 1)
stringValue.Length | length(stringValue)
stringValue.PadLeft(length) | lpad(stringValue, length)
stringValue.PadLeft(length, char) | lpad(stringValue, length, char)
stringValue.PadRight(length) | rpad(stringValue, length)
stringValue.PadRight(length, char) | rpad(stringValue, length, char)
stringValue.Replace(oldValue, newValue) | replace(stringValue, oldValue, newValue)
stringValue.StartsWith(value) | stringValue LIKE value \|\| '%'
stringValue.PadLeft(length) | CASE WHEN length(stringValue) >= length THEN stringValue ELSE lpad(stringValue, length) END
stringValue.PadLeft(length, char) | CASE WHEN length(stringValue) >= length THEN stringValue ELSE lpad(stringValue, length, char) END
stringValue.PadRight(length) | CASE WHEN length(stringValue) >= length THEN stringValue ELSE rpad(stringValue, length) END
stringValue.PadRight(length, char) | CASE WHEN length(stringValue) >= length THEN stringValue ELSE rpad(stringValue, length, char) END
stringValue.Replace(oldValue, newValue) | replace(stringValue, oldValue, newValue) | char overload added in 11.0
stringValue.StartsWith(value) | stringValue LIKE value \|\| '%' | char overload added in 11.0
stringValue.Substring(startIndex, length) | substr(stringValue, startIndex + 1, @length)
stringValue.ToLower() | lower(stringValue)
stringValue.ToUpper() | upper(stringValue)
Expand Down Expand Up @@ -57,6 +57,8 @@ EF.Functions.StringToArray(s, "\|", "FOO") | [string_agg(s, '
>
> See also Npgsql's [NodaTime support](/efcore/mapping/nodatime.html), which is a better and safer way of interacting with date/time data.

Starting with version 11.0, `EF.Functions.DateTrunc()` supports `DateTime`, `DateTimeOffset` and `TimeSpan`. The optional time zone argument is only supported for values mapped to `timestamp with time zone`; when omitted for such values, PostgreSQL uses the session time zone.

.NET | SQL | Notes
----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | --------
DateTime.UtcNow (6.0+) | [now()](https://www.postgresql.org/docs/current/functions-datetime.html) |
Expand All @@ -65,6 +67,8 @@ DateTime.Today (6.0+) | [date_trunc(
DateTime.UtcNow (legacy) | [now() AT TIME ZONE 'UTC'](https://www.postgresql.org/docs/current/functions-datetime.html) |
DateTime.Now (legacy) | [now()](https://www.postgresql.org/docs/current/functions-datetime.html) |
DateTime.Today (legacy) | [date_trunc('day', now())](https://www.postgresql.org/docs/current/functions-datetime.html) |
EF.Functions.DateTrunc("month", value) | [date_trunc('month', value)](https://www.postgresql.org/docs/current/functions-datetime.html) | Added in 11.0
EF.Functions.DateTrunc("month", utcDateTime, "Europe/Berlin") | [date_trunc('month', utcDateTime, 'Europe/Berlin')](https://www.postgresql.org/docs/current/functions-datetime.html) | Added in 11.0; timestamp with time zone only
dateTime.AddDays(1) | [dateTime + INTERVAL '1 days'](https://www.postgresql.org/docs/current/functions-datetime.html#OPERATORS-DATETIME-TABLE) |
dateTime.AddHours(value) | [dateTime + INTERVAL '1 hours'](https://www.postgresql.org/docs/current/functions-datetime.html#OPERATORS-DATETIME-TABLE) |
dateTime.AddMinutes(1) | [dateTime + INTERVAL '1 minutes'](https://www.postgresql.org/docs/current/functions-datetime.html#OPERATORS-DATETIME-TABLE) |
Expand Down Expand Up @@ -111,23 +115,46 @@ new DateTime(y, m, d, h, m, s, kind) | [make_timest
EF.Functions.Sum(timespans) | [sum(timespans)](https://www.postgresql.org/docs/current/functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE) | See [Aggregate functions](#aggregate-functions).
EF.Functions.Average(timespans) | [avg(timespans)](https://www.postgresql.org/docs/current/functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE) | See [Aggregate functions](#aggregate-functions).

## JSON functions

See [JSON mapping](json.md) for mapping options and [PostgreSQL's JSON functions and operators](https://www.postgresql.org/docs/current/functions-json.html) for operator semantics. JSON aggregate functions are listed under [Aggregate functions](#aggregate-functions).

.NET | SQL | Notes
----------------------------------------------- | ------------------------------------ | -----
EF.Functions.JsonContains(json, contained) | json @> contained | jsonb only
EF.Functions.JsonContained(contained, json) | contained <@ json | jsonb only
EF.Functions.JsonExists(json, key) | json ? key | jsonb only
EF.Functions.JsonExistAny(json, key1, key2) | json ?\| ARRAY[key1, key2] | jsonb only
EF.Functions.JsonExistAll(json, key1, key2) | json ?& ARRAY[key1, key2] | jsonb only
EF.Functions.JsonTypeof(json) | jsonb_typeof(json) or json_typeof(json) | Selected according to the mapped column type
EF.Functions.JsonPathExists(json, "$.Age") | JSON_EXISTS(json, '$.Age') | Added in 11.0; requires PostgreSQL 17 or above

## Miscellaneous functions

.NET | SQL
---------------------------------------- | --------------------
.NET | SQL | Notes
---------------------------------------- | -------------------- | -----
collection.Contains(item) | item IN collection
enumValue.HasFlag(flag) | enumValue & flag = flag
Guid.CreateVersion7() | [uuidv7()](https://www.postgresql.org/docs/current/functions-uuid.html) (added in 10 when targeting PG18, client-evaluated otherwise)
Guid.NewGuid() | [gen_random_uuid()](https://www.postgresql.org/docs/current/functions-uuid.html), or [uuid_generate_v4()](https://www.postgresql.org/docs/current/uuid-ossp.html) from [`uuid-ossp`](https://www.postgresql.org/docs/current/uuid-ossp.html) when targeting pre-PG13
nullable.GetValueOrDefault() | coalesce(nullable, 0)
nullable.GetValueOrDefault(defaultValue) | coalesce(nullable, defaultValue)
bool.Parse(stringValue) | CAST(stringValue AS boolean) | Added in 11.0
byte.Parse(stringValue) | CAST(stringValue AS smallint) | Added in 11.0
short.Parse(stringValue) | CAST(stringValue AS smallint) | Added in 11.0
int.Parse(stringValue) | CAST(stringValue AS integer) | Added in 11.0
long.Parse(stringValue) | CAST(stringValue AS bigint) | Added in 11.0
float.Parse(stringValue) | CAST(stringValue AS real) | Added in 11.0
double.Parse(stringValue) | CAST(stringValue AS double precision) | Added in 11.0
decimal.Parse(stringValue) | CAST(stringValue AS numeric) | Added in 11.0

## Binary functions

.NET | SQL | Notes
---------------------------- | ------------------------------- | --------
bytes[i] | get_byte(bytes, i) |
bytes.Contains(value) | position(value IN bytes) > 0 |
bytes.Any() | length(bytes) > 0 | Added in 11.0
bytes.Length | length(@bytes) |
bytes1.SequenceEqual(bytes2) | @bytes = @second |

Expand Down Expand Up @@ -315,6 +342,7 @@ The PostgreSQL aggregate functions are documented [here](https://www.postgresql.
| EF.Functions.Sum(timespans) | sum(timespans)
| EF.Functions.Average(timespans) | avg(timespans)
| EF.Functions.JsonObjectAgg(tuple_of_2) | json_object_agg(tuple_of_2.first, tuple_of_2.second)
| EF.Functions.JsonbObjectAgg(tuple_of_2) | jsonb_object_agg(tuple_of_2.first, tuple_of_2.second)
| ranges.RangeAgg() | range_agg(ranges)
| ranges.RangeIntersectAgg() | range_intersect_agg(ranges)
| multiranges.RangeIntersectAgg() | range_intersect_agg(multiranges)
Expand Down
Loading
Loading