Skip to content

Commit f269028

Browse files
CopilotAndriySvyryd
andcommitted
Address review feedback: improve docs clarity, add context, fix consistency
Co-authored-by: AndriySvyryd <[email protected]>
1 parent 1440b77 commit f269028

File tree

5 files changed

+49
-60
lines changed

5 files changed

+49
-60
lines changed

entity-framework/core/providers/sqlite/value-generation.md

Lines changed: 20 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This page details value generation configuration and patterns that are specific
1111

1212
## AUTOINCREMENT columns
1313

14-
By convention, numeric primary key columns that are configured to have their values generated on add are set up with SQLite's AUTOINCREMENT feature. Starting with EF Core 10, SQLite AUTOINCREMENT is a first-class feature with full support through conventions and the Fluent API.
14+
By convention, numeric primary key columns that are configured to have their values generated on add are set up with [SQLite's AUTOINCREMENT feature](https://sqlite.org/autoinc.html). Starting with EF Core 10, SQLite AUTOINCREMENT is implemented through conventions and the Fluent API, so it can be enabled or disabled as necessary.
1515

1616
### Configuring AUTOINCREMENT
1717

@@ -21,51 +21,29 @@ By convention, integer primary keys are automatically configured with AUTOINCREM
2121

2222
## Disabling AUTOINCREMENT for default SQLite value generation
2323

24-
In some cases, you may want to disable AUTOINCREMENT and use SQLite's default value generation behavior instead. You can do this using the Metadata API:
24+
AUTOINCREMENT imposes extra CPU, memory, disk space, and disk I/O overhead compared to the default key generation algorithm in SQLite - [ROWID](https://sqlite.org/lang_createtable.html#rowid). The downside of `ROWID` is that it reuses values from deleted rows. If your scenario wouldn't be affected by this, you may want to disable AUTOINCREMENT and use SQLite's default value generation behavior instead. You can do this using the Metadata API:
2525

26+
<!--
27+
protected override void OnModelCreating(ModelBuilder modelBuilder)
28+
{
29+
modelBuilder.Entity<Blog>()
30+
.Property(b => b.Id)
31+
.Metadata.SetValueGenerationStrategy(SqliteValueGenerationStrategy.None);
32+
}
33+
-->
2634
[!code-csharp[Main](../../../../samples/core/Sqlite/ValueGeneration/SqliteValueGenerationStrategyNone.cs?name=SqliteValueGenerationStrategyNone&highlight=5)]
2735

28-
Starting with EF Core 10, you can also use the strongly-typed Metadata API:
29-
30-
```csharp
31-
protected override void OnModelCreating(ModelBuilder modelBuilder)
32-
{
33-
modelBuilder.Entity<Post>()
34-
.Property(p => p.Id)
35-
.Metadata.SetValueGenerationStrategy(SqliteValueGenerationStrategy.None);
36-
}
37-
```
38-
3936
Alternatively, you can disable value generation entirely:
4037

41-
```csharp
42-
protected override void OnModelCreating(ModelBuilder modelBuilder)
43-
{
44-
modelBuilder.Entity<Blog>()
45-
.Property(b => b.Id)
46-
.ValueGeneratedNever();
47-
}
48-
```
49-
50-
This means that it's up to the application to supply a value for the property before saving to the database. Note that this still won't disable the default value generation server-side, so non-EF usages could still get a generated value. To completely disable value generation the user can change the column type from `INTEGER` to `INT`.
51-
52-
## Migration behavior
53-
54-
When EF Core generates migrations for SQLite AUTOINCREMENT columns, the generated migration will include the `Sqlite:Autoincrement` annotation:
55-
56-
```csharp
57-
migrationBuilder.CreateTable(
58-
name: "Blogs",
59-
columns: table => new
38+
<!--
39+
protected override void OnModelCreating(ModelBuilder modelBuilder)
6040
{
61-
Id = table.Column<int>(type: "INTEGER", nullable: false)
62-
.Annotation("Sqlite:Autoincrement", true),
63-
Title = table.Column<string>(type: "TEXT", nullable: true)
64-
},
65-
constraints: table =>
66-
{
67-
table.PrimaryKey("PK_Blogs", x => x.Id);
68-
});
69-
```
41+
modelBuilder.Entity<Blog>()
42+
.Property(b => b.Id)
43+
.ValueGeneratedNever();
44+
}
45+
-->
46+
[!code-csharp[Main](../../../../samples/core/Sqlite/ValueGeneration/SqliteValueGeneratedNever.cs?name=SqliteValueGeneratedNever&highlight=5)]
47+
48+
This means that it's up to the application to supply a value for the property before saving to the database. Note that this still won't disable the default value generation server-side, so non-EF usages could still get a generated value. To [completely disable value generation](https://sqlite.org/lang_createtable.html#rowids_and_the_integer_primary_key) the user can change the column type from `INTEGER` to `INT`.
7049

71-
This ensures that the AUTOINCREMENT feature is properly applied when the migration is executed against the SQLite database.

entity-framework/core/what-is-new/ef-core-10.0/whatsnew.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -628,20 +628,11 @@ await context.Blogs.ExecuteUpdateAsync(s =>
628628

629629
Thanks to [@aradalvand](https://github.com/aradalvand) for proposing and pushing for this change (in [#32018](https://github.com/dotnet/efcore/issues/32018)).
630630

631-
<a name="sqlite"></a>
632-
633-
## SQLite
634-
635-
### Improved AUTOINCREMENT support
636-
637-
SQLite AUTOINCREMENT is now a first-class feature with full support through conventions and the Fluent API. Previously, properties with value converters couldn't configure AUTOINCREMENT and would cause false pending model change warnings.
638-
639-
For more information, see [SQLite Value Generation](xref:core/providers/sqlite/value-generation).
640-
641631
<a name="other-improvements"></a>
642632

643633
## Other improvements
644634

635+
- AUTOINCREMENT can now be disabled for SQLite and is also supported for properties with value converters. For more information, see [SQLite Value Generation](xref:core/providers/sqlite/value-generation).
645636
- Make SQL Server scaffolding compatible with Azure Data Explorer ([#34832](https://github.com/dotnet/efcore/pull/34832), contributed by [@barnuri](https://github.com/barnuri)).
646637
- Associate the DatabaseRoot with the scoped options instance and not the singleton options ([#34477](https://github.com/dotnet/efcore/pull/34477), contributed by [@koenigst](https://github.com/koenigst)).
647638
- Redact inlined constants from log when sensitive logging is off ([#35724](https://github.com/dotnet/efcore/pull/35724)).

samples/core/Sqlite/ValueGeneration/SqliteAutoincrementWithValueConverter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ public readonly struct BlogId
1313

1414
public class SqliteAutoincrementWithValueConverterContext : DbContext
1515
{
16-
public DbSet<BlogPost> Blogs { get; set; }
16+
public DbSet<Blog> Blogs { get; set; }
1717

1818
#region SqliteAutoincrementWithValueConverter
1919
protected override void OnModelCreating(ModelBuilder modelBuilder)
2020
{
21-
modelBuilder.Entity<BlogPost>()
21+
modelBuilder.Entity<Blog>()
2222
.Property(b => b.Id)
2323
.HasConversion<int>()
2424
.UseAutoincrement();
@@ -29,7 +29,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
2929
=> optionsBuilder.UseSqlite("Data Source=sample.db");
3030
}
3131

32-
public class BlogPost
32+
public class Blog
3333
{
3434
public BlogId Id { get; set; }
3535
public string Title { get; set; }
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace EFCore.Sqlite.ValueGeneration;
4+
5+
public class SqliteValueGeneratedNeverContext : DbContext
6+
{
7+
public DbSet<Blog> Blogs { get; set; }
8+
9+
#region SqliteValueGeneratedNever
10+
protected override void OnModelCreating(ModelBuilder modelBuilder)
11+
{
12+
modelBuilder.Entity<Blog>()
13+
.Property(b => b.Id)
14+
.ValueGeneratedNever();
15+
}
16+
#endregion
17+
18+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
19+
=> optionsBuilder.UseSqlite("Data Source=sample.db");
20+
}

samples/core/Sqlite/ValueGeneration/SqliteValueGenerationStrategyNone.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ namespace EFCore.Sqlite.ValueGeneration;
55

66
public class SqliteValueGenerationStrategyNoneContext : DbContext
77
{
8-
public DbSet<Post> Posts { get; set; }
8+
public DbSet<Blog> Blogs { get; set; }
99

1010
#region SqliteValueGenerationStrategyNone
1111
protected override void OnModelCreating(ModelBuilder modelBuilder)
1212
{
13-
modelBuilder.Entity<Post>()
14-
.Property(p => p.Id)
13+
modelBuilder.Entity<Blog>()
14+
.Property(b => b.Id)
1515
.Metadata.SetValueGenerationStrategy(SqliteValueGenerationStrategy.None);
1616
}
1717
#endregion
@@ -20,8 +20,8 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
2020
=> optionsBuilder.UseSqlite("Data Source=sample.db");
2121
}
2222

23-
public class Post
23+
public class Blog
2424
{
2525
public int Id { get; set; }
26-
public string Content { get; set; }
26+
public string Title { get; set; }
2727
}

0 commit comments

Comments
 (0)