Skip to content

Commit 80833b6

Browse files
Document SpatiaLite incompatibility with Microsoft.Data.Sqlite on macOS/Linux (#5309)
Fixes #5308 Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
1 parent 8b69093 commit 80833b6

1 file changed

Lines changed: 155 additions & 142 deletions

File tree

Lines changed: 155 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,142 +1,155 @@
1-
---
2-
title: SQLite Database Provider - Spatial Data - EF Core
3-
description: Using spatial data with the Entity Framework Core SQLite database provider
4-
author: SamMonoRT
5-
ms.date: 10/02/2020
6-
uid: core/providers/sqlite/spatial
7-
---
8-
# Spatial Data in the SQLite EF Core Provider
9-
10-
This page includes additional information about using spatial data with the SQLite database provider. For general information about using spatial data in EF Core, see the main [Spatial Data](xref:core/modeling/spatial) documentation.
11-
12-
## Installing SpatiaLite
13-
14-
On Windows, the native `mod_spatialite` library is distributed as a [NuGet package](https://www.nuget.org/packages/mod_spatialite) dependency. Other platforms need to install it separately. This is typically done using a software package manager. For example, you can use APT on Debian and Ubuntu; and Homebrew on MacOS.
15-
16-
```bash
17-
# Debian/Ubuntu
18-
apt-get install libsqlite3-mod-spatialite
19-
20-
# macOS
21-
brew install libspatialite
22-
```
23-
24-
Unfortunately, newer versions of PROJ (a dependency of SpatiaLite) are incompatible with EF's default [SQLitePCLRaw bundle](/dotnet/standard/data/sqlite/custom-versions#bundles). You can work around this by using the system SQLite library instead.
25-
26-
```xml
27-
<ItemGroup>
28-
<!-- Use bundle_sqlite3 instead with SpatiaLite on macOS and Linux -->
29-
<!--<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.0" />-->
30-
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="3.1.0" />
31-
<PackageReference Include="SQLitePCLRaw.bundle_sqlite3" Version="2.0.4" />
32-
33-
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite" Version="3.1.0" />
34-
</ItemGroup>
35-
```
36-
37-
On **macOS**, you'll also need set an environment variable before running your app so it uses Homebrew's version of SQLite. In Visual Studio for Mac, you can set this under **Project > Project Options > Run > Configurations > Default**
38-
39-
```bash
40-
DYLD_LIBRARY_PATH=/usr/local/opt/sqlite/lib
41-
```
42-
43-
## Configuring SRID
44-
45-
In SpatiaLite, columns need to specify an SRID per column. The default SRID is `0`. Specify a different SRID using the HasSrid method.
46-
47-
```csharp
48-
modelBuilder.Entity<City>().Property(c => c.Location)
49-
.HasSrid(4326);
50-
```
51-
52-
> [!NOTE]
53-
> 4326 refers to WGS 84, a standard used in GPS and other geographic systems.
54-
55-
## Dimension
56-
57-
The default dimension (or ordinates) of a column is X and Y. To enable additional ordinates like Z or M, configure the column type.
58-
59-
```csharp
60-
modelBuilder.Entity<City>().Property(c => c.Location)
61-
.HasColumnType("POINTZ");
62-
```
63-
64-
## Spatial function mappings
65-
66-
This table shows which [NetTopologySuite](https://nettopologysuite.github.io/NetTopologySuite/) (NTS) members are translated into which SQL functions.
67-
68-
.NET | SQL
69-
------------------------------------------- | ---
70-
geometry.Area | Area(@geometry)
71-
geometry.AsBinary() | AsBinary(@geometry)
72-
geometry.AsText() | AsText(@geometry)
73-
geometry.Boundary | Boundary(@geometry)
74-
geometry.Buffer(distance) | Buffer(@geometry, @distance)
75-
geometry.Buffer(distance, quadrantSegments) | Buffer(@geometry, @distance, @quadrantSegments)
76-
geometry.Centroid | Centroid(@geometry)
77-
geometry.Contains(g) | Contains(@geometry, @g)
78-
geometry.ConvexHull() | ConvexHull(@geometry)
79-
geometry.CoveredBy(g) | CoveredBy(@geometry, @g)
80-
geometry.Covers(g) | Covers(@geometry, @g)
81-
geometry.Crosses(g) | Crosses(@geometry, @g)
82-
geometry.Difference(other) | Difference(@geometry, @other)
83-
geometry.Dimension | Dimension(@geometry)
84-
geometry.Disjoint(g) | Disjoint(@geometry, @g)
85-
geometry.Distance(g) | Distance(@geometry, @g)
86-
geometry.Envelope | Envelope(@geometry)
87-
geometry.EqualsTopologically(g) | Equals(@geometry, @g)
88-
geometry.GeometryType | GeometryType(@geometry)
89-
geometry.GetGeometryN(n) | GeometryN(@geometry, @n + 1)
90-
geometry.InteriorPoint | PointOnSurface(@geometry)
91-
geometry.Intersection(other) | Intersection(@geometry, @other)
92-
geometry.Intersects(g) | Intersects(@geometry, @g)
93-
geometry.IsEmpty | IsEmpty(@geometry)
94-
geometry.IsSimple | IsSimple(@geometry)
95-
geometry.IsValid | IsValid(@geometry)
96-
geometry.IsWithinDistance(geom, distance) | Distance(@geometry, @geom) <= @distance
97-
geometry.Length | GLength(@geometry)
98-
geometry.NumGeometries | NumGeometries(@geometry)
99-
geometry.NumPoints | NumPoints(@geometry)
100-
geometry.OgcGeometryType | CASE GeometryType(@geometry) WHEN 'POINT' THEN 1 ... END
101-
geometry.Overlaps(g) | Overlaps(@geometry, @g)
102-
geometry.PointOnSurface | PointOnSurface(@geometry)
103-
geometry.Relate(g, intersectionPattern) | Relate(@geometry, @g, @intersectionPattern)
104-
geometry.Reverse() | ST_Reverse(@geometry)
105-
geometry.SRID | SRID(@geometry)
106-
geometry.SymmetricDifference(other) | SymDifference(@geometry, @other)
107-
geometry.ToBinary() | AsBinary(@geometry)
108-
geometry.ToText() | AsText(@geometry)
109-
geometry.Touches(g) | Touches(@geometry, @g)
110-
geometry.Union() | UnaryUnion(@geometry)
111-
geometry.Union(other) | GUnion(@geometry, @other)
112-
geometry.Within(g) | Within(@geometry, @g)
113-
geometryCollection[i] | GeometryN(@geometryCollection, @i + 1)
114-
geometryCollection.Count | NumGeometries(@geometryCollection)
115-
lineString.Count | NumPoints(@lineString)
116-
lineString.EndPoint | EndPoint(@lineString)
117-
lineString.GetPointN(n) | PointN(@lineString, @n + 1)
118-
lineString.IsClosed | IsClosed(@lineString)
119-
lineString.IsRing | IsRing(@lineString)
120-
lineString.StartPoint | StartPoint(@lineString)
121-
multiLineString.IsClosed | IsClosed(@multiLineString)
122-
point.M | M(@point)
123-
point.X | X(@point)
124-
point.Y | Y(@point)
125-
point.Z | Z(@point)
126-
polygon.ExteriorRing | ExteriorRing(@polygon)
127-
polygon.GetInteriorRingN(n) | InteriorRingN(@polygon, @n + 1)
128-
polygon.NumInteriorRings | NumInteriorRing(@polygon)
129-
130-
### Aggregate functions
131-
132-
.NET | SQL | Added in
133-
----------------------------------------------------------------- | ----------------------------- | --------
134-
GeometryCombiner.Combine(group.Select(x => x.Property)) | Collect(Property) | EF Core 7.0
135-
ConvexHull.Create(group.Select(x => x.Property)) | ConvexHull(Collect(Property)) | EF Core 7.0
136-
UnaryUnionOp.Union(group.Select(x => x.Property)) | GUnion(Property) | EF Core 7.0
137-
EnvelopeCombiner.CombineAsGeometry(group.Select(x => x.Property)) | Extent(Property) | EF Core 7.0
138-
139-
## Additional resources
140-
141-
* [SpatiaLite Homepage](https://www.gaia-gis.it/fossil/libspatialite)
142-
* [NetTopologySuite API Documentation](https://nettopologysuite.github.io/NetTopologySuite/api/NetTopologySuite.html)
1+
---
2+
title: SQLite Database Provider - Spatial Data - EF Core
3+
description: Using spatial data with the Entity Framework Core SQLite database provider
4+
author: SamMonoRT
5+
ms.date: 03/27/2026
6+
uid: core/providers/sqlite/spatial
7+
---
8+
# Spatial Data in the SQLite EF Core Provider
9+
10+
This page includes additional information about using spatial data with the SQLite database provider. For general information about using spatial data in EF Core, see the main [Spatial Data](xref:core/modeling/spatial) documentation.
11+
12+
## Installing SpatiaLite
13+
14+
On Windows, the native `mod_spatialite` library is distributed as a [NuGet package](https://www.nuget.org/packages/mod_spatialite) dependency. Other platforms need to install it separately. This is typically done using a software package manager. For example, you can use APT on Debian and Ubuntu; and Homebrew on MacOS.
15+
16+
```bash
17+
# Debian/Ubuntu
18+
apt-get install libsqlite3-mod-spatialite
19+
20+
# macOS
21+
brew install libspatialite
22+
```
23+
24+
Unfortunately, newer versions of PROJ (a dependency of SpatiaLite) are incompatible with EF's default [SQLitePCLRaw bundle](/dotnet/standard/data/sqlite/custom-versions#bundles). You can work around this by using the system SQLite library instead.
25+
26+
> [!IMPORTANT]
27+
> Don't use `Microsoft.EntityFrameworkCore.Sqlite` or `Microsoft.Data.Sqlite` with SpatiaLite on macOS and Linux. Both packages pull in `SQLitePCLRaw.bundle_e_sqlite3` by default—a bundled version of SQLite that is incompatible with system-installed Sqlite. Using it may result in a silent crash at run time. Use `Microsoft.EntityFrameworkCore.Sqlite.Core` or `Microsoft.Data.Sqlite.Core` instead, together with the system SQLite provider as shown below.
28+
29+
Replace `Microsoft.EntityFrameworkCore.Sqlite` with `Microsoft.EntityFrameworkCore.Sqlite.Core` and reference the `SQLitePCLRaw.provider.sqlite3` package to use the system SQLite library:
30+
31+
```xml
32+
<ItemGroup>
33+
<!-- Use Sqlite.Core with the system SQLite provider instead of Microsoft.EntityFrameworkCore.Sqlite -->
34+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="10.0.0" />
35+
<PackageReference Include="SQLitePCLRaw.provider.sqlite3" Version="2.1.10" />
36+
37+
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite" Version="10.0.0" />
38+
</ItemGroup>
39+
```
40+
41+
> [!NOTE]
42+
> Starting with EF Core 11 (SQLitePCLRaw 3.0), replace the `SQLitePCLRaw.provider.sqlite3` version with `3.x.x`. See the [breaking changes](xref:core/what-is-new/ef-core-11.0/breaking-changes#sqlite-bundles-removed) for details.
43+
44+
Then add explicit initialization before using SQLite:
45+
46+
```csharp
47+
SQLitePCL.raw.SetProvider(new SQLitePCL.SQLite3Provider_sqlite3());
48+
```
49+
50+
On **macOS**, you'll also need to set an environment variable before running your app so it uses Homebrew's version of SQLite:
51+
52+
```bash
53+
DYLD_LIBRARY_PATH="$(brew --prefix sqlite)/lib"
54+
```
55+
56+
## Configuring SRID
57+
58+
In SpatiaLite, columns need to specify an SRID per column. The default SRID is `0`. Specify a different SRID using the HasSrid method.
59+
60+
```csharp
61+
modelBuilder.Entity<City>().Property(c => c.Location)
62+
.HasSrid(4326);
63+
```
64+
65+
> [!NOTE]
66+
> 4326 refers to WGS 84, a standard used in GPS and other geographic systems.
67+
68+
## Dimension
69+
70+
The default dimension (or ordinates) of a column is X and Y. To enable additional ordinates like Z or M, configure the column type.
71+
72+
```csharp
73+
modelBuilder.Entity<City>().Property(c => c.Location)
74+
.HasColumnType("POINTZ");
75+
```
76+
77+
## Spatial function mappings
78+
79+
This table shows which [NetTopologySuite](https://nettopologysuite.github.io/NetTopologySuite/) (NTS) members are translated into which SQL functions.
80+
81+
.NET | SQL
82+
------------------------------------------- | ---
83+
geometry.Area | Area(@geometry)
84+
geometry.AsBinary() | AsBinary(@geometry)
85+
geometry.AsText() | AsText(@geometry)
86+
geometry.Boundary | Boundary(@geometry)
87+
geometry.Buffer(distance) | Buffer(@geometry, @distance)
88+
geometry.Buffer(distance, quadrantSegments) | Buffer(@geometry, @distance, @quadrantSegments)
89+
geometry.Centroid | Centroid(@geometry)
90+
geometry.Contains(g) | Contains(@geometry, @g)
91+
geometry.ConvexHull() | ConvexHull(@geometry)
92+
geometry.CoveredBy(g) | CoveredBy(@geometry, @g)
93+
geometry.Covers(g) | Covers(@geometry, @g)
94+
geometry.Crosses(g) | Crosses(@geometry, @g)
95+
geometry.Difference(other) | Difference(@geometry, @other)
96+
geometry.Dimension | Dimension(@geometry)
97+
geometry.Disjoint(g) | Disjoint(@geometry, @g)
98+
geometry.Distance(g) | Distance(@geometry, @g)
99+
geometry.Envelope | Envelope(@geometry)
100+
geometry.EqualsTopologically(g) | Equals(@geometry, @g)
101+
geometry.GeometryType | GeometryType(@geometry)
102+
geometry.GetGeometryN(n) | GeometryN(@geometry, @n + 1)
103+
geometry.InteriorPoint | PointOnSurface(@geometry)
104+
geometry.Intersection(other) | Intersection(@geometry, @other)
105+
geometry.Intersects(g) | Intersects(@geometry, @g)
106+
geometry.IsEmpty | IsEmpty(@geometry)
107+
geometry.IsSimple | IsSimple(@geometry)
108+
geometry.IsValid | IsValid(@geometry)
109+
geometry.IsWithinDistance(geom, distance) | Distance(@geometry, @geom) <= @distance
110+
geometry.Length | GLength(@geometry)
111+
geometry.NumGeometries | NumGeometries(@geometry)
112+
geometry.NumPoints | NumPoints(@geometry)
113+
geometry.OgcGeometryType | CASE GeometryType(@geometry) WHEN 'POINT' THEN 1 ... END
114+
geometry.Overlaps(g) | Overlaps(@geometry, @g)
115+
geometry.PointOnSurface | PointOnSurface(@geometry)
116+
geometry.Relate(g, intersectionPattern) | Relate(@geometry, @g, @intersectionPattern)
117+
geometry.Reverse() | ST_Reverse(@geometry)
118+
geometry.SRID | SRID(@geometry)
119+
geometry.SymmetricDifference(other) | SymDifference(@geometry, @other)
120+
geometry.ToBinary() | AsBinary(@geometry)
121+
geometry.ToText() | AsText(@geometry)
122+
geometry.Touches(g) | Touches(@geometry, @g)
123+
geometry.Union() | UnaryUnion(@geometry)
124+
geometry.Union(other) | GUnion(@geometry, @other)
125+
geometry.Within(g) | Within(@geometry, @g)
126+
geometryCollection[i] | GeometryN(@geometryCollection, @i + 1)
127+
geometryCollection.Count | NumGeometries(@geometryCollection)
128+
lineString.Count | NumPoints(@lineString)
129+
lineString.EndPoint | EndPoint(@lineString)
130+
lineString.GetPointN(n) | PointN(@lineString, @n + 1)
131+
lineString.IsClosed | IsClosed(@lineString)
132+
lineString.IsRing | IsRing(@lineString)
133+
lineString.StartPoint | StartPoint(@lineString)
134+
multiLineString.IsClosed | IsClosed(@multiLineString)
135+
point.M | M(@point)
136+
point.X | X(@point)
137+
point.Y | Y(@point)
138+
point.Z | Z(@point)
139+
polygon.ExteriorRing | ExteriorRing(@polygon)
140+
polygon.GetInteriorRingN(n) | InteriorRingN(@polygon, @n + 1)
141+
polygon.NumInteriorRings | NumInteriorRing(@polygon)
142+
143+
### Aggregate functions
144+
145+
.NET | SQL | Added in
146+
----------------------------------------------------------------- | ----------------------------- | --------
147+
GeometryCombiner.Combine(group.Select(x => x.Property)) | Collect(Property) | EF Core 7.0
148+
ConvexHull.Create(group.Select(x => x.Property)) | ConvexHull(Collect(Property)) | EF Core 7.0
149+
UnaryUnionOp.Union(group.Select(x => x.Property)) | GUnion(Property) | EF Core 7.0
150+
EnvelopeCombiner.CombineAsGeometry(group.Select(x => x.Property)) | Extent(Property) | EF Core 7.0
151+
152+
## Additional resources
153+
154+
* [SpatiaLite Homepage](https://www.gaia-gis.it/fossil/libspatialite)
155+
* [NetTopologySuite API Documentation](https://nettopologysuite.github.io/NetTopologySuite/api/NetTopologySuite.html)

0 commit comments

Comments
 (0)