|
4 | 4 |
|
5 | 5 | Adds support for [NodaTime](https://github.com/nodatime/nodatime) types when using [SQLite](https://sqlite.org/) with [Entity Framework Core](https://github.com/dotnet/efcore). |
6 | 6 |
|
7 | | -## Installation |
8 | | - |
9 | | -[](https://www.nuget.org/packages/EntityFrameworkCore.Sqlite.NodaTime) |
10 | | - |
11 | | -Install the latest package from [NuGet](https://www.nuget.org/packages/EntityFrameworkCore.Sqlite.NodaTime). |
12 | | - |
13 | | -## Getting Started |
14 | | - |
15 | | -If you're using Entity Framework Core without Dependency Injection, you can call `UseNodaTime` inside the `OnConfiguring` method in your `DbContext` class: |
16 | | - |
17 | | -```csharp |
18 | | -public class MyDbContext : DbContext |
19 | | -{ |
20 | | - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) |
21 | | - { |
22 | | - optionsBuilder.UseSqlite("<connection-string>", x => x.UseNodaTime()); |
23 | | - } |
24 | | -} |
25 | | -``` |
26 | | - |
27 | | -Otherwise, you should call `UseNodaTime` when adding the `DbContext` to your service collection: |
28 | | - |
29 | | -```csharp |
30 | | -public class Startup |
31 | | -{ |
32 | | - public void ConfigureServices(IServiceCollection services) |
33 | | - { |
34 | | - services.AddDbContext<MyDbContext>(options => |
35 | | - options.UseSqlite("<connection-string>", x => x.UseNodaTime())); |
36 | | - } |
37 | | -} |
38 | | -``` |
39 | | - |
40 | | -And that's it. You can now use NodaTime types in your entities and perform server-side queries on them! :sparkles: |
41 | | - |
42 | | -## Supported Types |
43 | | - |
44 | | -The following NodaTime types are currently supported: |
45 | | - |
46 | | -| NodaTime Type | SQLite Type | SQLite Format | |
47 | | -|---------------|-------------|---------------| |
48 | | -| `Instant` | `TEXT` | `YYYY-MM-DD HH:MM:SS.SSS` | |
49 | | -| `LocalDateTime` | `TEXT` | `YYYY-MM-DD HH:MM:SS.SSS` | |
50 | | -| `LocalDate` | `TEXT` | `YYYY-MM-DD` | |
51 | | -| `LocalTime` | `TEXT` | `HH:MM:SS.SSS` | |
52 | | - |
53 | | -# Supported Properties |
54 | | - |
55 | | -| NodaTime Property | Generated SQL | Notes | |
56 | | -|-------------------|--------------|-------| |
57 | | -| `Year` | `strftime('%Y', <column>)` | The value is cast to `INTEGER` for comparison. | |
58 | | -| `Month` | `strftime('%m', <column>)` | The value is cast to `INTEGER` for comparison. | |
59 | | -| `Day` | `strftime('%d', <column>)` | The value is cast to `INTEGER` for comparison. | |
60 | | -| `Hour` | `strftime('%H', <column>)` | The value is cast to `INTEGER` for comparison. | |
61 | | -| `Minute` | `strftime('%M', <column>)` | The value is cast to `INTEGER` for comparison. | |
62 | | -| `Second` | `strftime('%S', <column>)` | The value is cast to `INTEGER` for comparison. | |
63 | | -| `DayOfYear` | `strftime('%j', <column>)` | The value is cast to `INTEGER` for comparison.| |
64 | | -| `DayOfWeek` | `strftime('%w', <column>)` | The value is cast to `INTEGER` for comparison. As NodaTime's `IsoDayOfWeek` enum doesn't match SQLite's day of week, additional SQL is emitted to convert `Sunday` to the correct value. | |
65 | | -| `Date` | `date(<column>)` | | |
66 | | -| `TimeOfDay` | `strftime('%H:%M:%f', <column>)` | In order to support fractional seconds to fully roundtrip `LocalTime`, a custom format string is used instead of using `time(<column>)`. | |
67 | | - |
68 | | -## Supported Methods |
69 | | - |
70 | | -| NodaTime Method | Generated SQL | |
71 | | -|-----------------|---------------| |
72 | | -| `SystemClock.Instance.GetCurrentInstant()` | `strftime('%Y-%m-%d %H:%M:%f', 'now')` | |
73 | | -| `LocalDate.PlusYears` | `date(<column>, '+n years')` | |
74 | | -| `LocalDate.PlusMonths` | `date(<column>, '+n months')` | |
75 | | -| `LocalDate.PlusWeeks` | `date(<column>, '+n*7 days')` | |
76 | | -| `LocalDate.PlusDays` | `date(<column>, '+n days')` | |
77 | | -| `LocalDate.ToDateOnly` | `date(<column>)` | |
78 | | -| `LocalDate.ToDateTimeUnspecified` | `date(<column>)` | |
79 | | -| `LocalTime.PlusHours` | `strftime('%H:%M:%f', <column>, '+n hours')` | |
80 | | -| `LocalTime.PlusMinutes` | `strftime('%H:%M:%f', <column>, '+n minutes')` | |
81 | | -| `LocalTime.PlusSeconds` | `strftime('%H:%M:%f', <column>, '+n seconds')` | |
82 | | -| `LocalTime.PlusMilliseconds` | `strftime('%H:%M:%f', <column>, '+0.n seconds')` | |
83 | | -| `LocalTime.ToTimeOnly` | `strftime('%H:%M:%f', <column>)` | |
84 | | -| `LocalDateTime.PlusYears` | `strftime('%Y-%m-%d %H:%M:%f',<column>, '+n years')` | |
85 | | -| `LocalDateTime.PlusMonths` | `strftime('%Y-%m-%d %H:%M:%f',<column>, '+n months')` | |
86 | | -| `LocalDateTime.PlusWeeks` | `strftime('%Y-%m-%d %H:%M:%f',<column>, '+n*7 days')` | |
87 | | -| `LocalDateTime.PlusDays` | `strftime('%Y-%m-%d %H:%M:%f',<column>, '+n days')` | |
88 | | -| `LocalDateTime.PlusHours` | `strftime('%Y-%m-%d %H:%M:%f', <column>, '+n hours')` | |
89 | | -| `LocalDateTime.PlusMinutes` | `strftime('%Y-%m-%d %H:%M:%f', <column>, '+n minutes')` | |
90 | | -| `LocalDateTime.PlusSeconds` | `strftime('%Y-%m-%d %H:%M:%f', <column>, '+n seconds')` | |
91 | | -| `LocalDateTime.PlusMilliseconds` | `strftime('%Y-%m-%d %H:%M:%f', <column>, '+0.n seconds')` | |
92 | | -| `LocalDateTime.ToDateTimeUnspecified` | `strftime('%Y-%m-%d %H:%M:%f', <column>)` | |
93 | | - |
94 | | -When these methods are chained, all modifiers will be added to the same function call, like this: |
95 | | - |
96 | | -```csharp |
97 | | -context.NodaTime.Select(x => x.LocalDateTime.PlusMonths(2).PlusDays(2).PlusHours(2).PlusSeconds(2)) |
98 | | -``` |
99 | | - |
100 | | -Results in the following SQL: |
101 | | - |
102 | | -```sql |
103 | | -SELECT strftime('%Y-%m-%d %H:%M:%f', "n"."LocalDateTime", '+2 months', '+2 days', '+2 hours', '+2 seconds') |
104 | | -``` |
| 7 | +Read more at [Learn Entity Framework Core](https://www.learnentityframeworkcore.com/extensions/entityframeworkcore-sqlite-nodatime) |
105 | 8 |
|
106 | 9 | ## Sponsors |
107 | 10 |
|
|
0 commit comments