Skip to content

Sqlite:Autoincrement is not generated for key column when the entity has owned property #34608

Closed

Description

@noelex

Consider the following configuration:

public class SomeRandomEntity
{
    public long Id { get; set; }

    public OwnedEntity? Owned { get; set; }
}

public class OwnedEntity
{
    public int OwnedField { get; set; }
}

internal class ReproDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite();
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SomeRandomEntity>(entity =>
        {
            entity.HasKey(x => x.Id);
            entity.OwnsOne(x => x.Owned);
        });
    }
}

dotnet ef migrations add generates a migration with the following code:

migrationBuilder.CreateTable(
    name: "SomeRandomEntity",
    columns: table => new
    {
        Id = table.Column<long>(type: "INTEGER", nullable: false),
        Owned_OwnedField = table.Column<int>(type: "INTEGER", nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_SomeRandomEntity", x => x.Id);
    });

Note that Sqlite:Autoincrement is missing on Id. This can be 'fixed' by either changing the name of the entity to MyEntity:

migrationBuilder.CreateTable(
    name: "MyEntity",
    columns: table => new
    {
        Id = table.Column<long>(type: "INTEGER", nullable: false)
            .Annotation("Sqlite:Autoincrement", true),
        Owned_OwnedField = table.Column<int>(type: "INTEGER", nullable: true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_MyEntity", x => x.Id);
    });

or by removing Owned property:

migrationBuilder.CreateTable(
    name: "SomeRandomEntity",
    columns: table => new
    {
        Id = table.Column<long>(type: "INTEGER", nullable: false)
            .Annotation("Sqlite:Autoincrement", true)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_SomeRandomEntity", x => x.Id);
    });

Reverting Microsoft.EntityFrameworkCore.Sqlite and Microsoft.EntityFrameworkCore.Design to 6.0.33 also fixes the issue.

EF Core version: 8.0.8
Database provider: Microsoft.EntityFrameworkCore.Sqlite
Target framework: net-8.0

Activity

  1. cincuranet commented on Sep 4, 2024

    @cincuranet
    Contributor

    Note: Works correctly with Microsoft.EntityFrameworkCore.SqlServer. So probably SQLite provider specific.

  2. self-assigned this
    on Sep 4, 2024
  3. added this to the Backlog milestone on Sep 4, 2024
  4. noelex commented on Sep 6, 2024

    @noelex
    Author

    var property = column.PropertyMappings.First().Property;

    This line might be problematic since PropertyMappings may contain a shadow ColumnMapping for the owned entity:

    ColumnMapping: OwnedEntity.SomeRandomEntityId - SomeRandomEntity.Id
    ColumnMapping: SomeRandomEntity.Id - SomeRandomEntity.Id
    

    Things will only work when the first ColumnMapping happens to be the right one.

    And these may also cause problems?

    /// <summary>
    /// Gets the maximum length of data that is allowed in this column. For example, if the property is a <see cref="string" /> '
    /// then this is the maximum number of characters.
    /// </summary>
    int? MaxLength
    => PropertyMappings.First().Property.GetMaxLength(StoreObjectIdentifier.Table(Table.Name, Table.Schema));
    /// <summary>
    /// Gets the precision of data that is allowed in this column. For example, if the property is a <see cref="decimal" /> '
    /// then this is the maximum number of digits.
    /// </summary>
    int? Precision
    => PropertyMappings.First().Property.GetPrecision(StoreObjectIdentifier.Table(Table.Name, Table.Schema));
    /// <summary>
    /// Gets the scale of data that is allowed in this column. For example, if the property is a <see cref="decimal" /> '
    /// then this is the maximum number of decimal places.
    /// </summary>
    int? Scale
    => PropertyMappings.First().Property.GetScale(StoreObjectIdentifier.Table(Table.Name, Table.Schema));
    /// <summary>
    /// Gets a value indicating whether or not the property can persist Unicode characters.
    /// </summary>
    bool? IsUnicode
    => PropertyMappings.First().Property.IsUnicode(StoreObjectIdentifier.Table(Table.Name, Table.Schema));
    /// <summary>
    /// Returns a flag indicating whether the property is capable of storing only fixed-length data, such as strings.
    /// </summary>
    bool? IsFixedLength
    => PropertyMappings.First().Property.IsFixedLength(StoreObjectIdentifier.Table(Table.Name, Table.Schema));
    /// <summary>
    /// Indicates whether or not this column acts as an automatic concurrency token by generating a different value
    /// on every update in the same vein as 'rowversion'/'timestamp' columns on SQL Server.
    /// </summary>
    bool IsRowVersion
    => PropertyMappings.First().Property.IsConcurrencyToken
    && PropertyMappings.First().Property.ValueGenerated == ValueGenerated.OnAddOrUpdate;
    /// <summary>
    /// Gets the column order.
    /// </summary>
    /// <value> The column order. </value>
    int? Order
    => PropertyMappings.First().Property.GetColumnOrder(StoreObjectIdentifier.Table(Table.Name, Table.Schema));

  5. added theissue type on Jun 15, 2025
  6. mauri0686 commented on Sep 27, 2026

    @mauri0686

    I checked this against current releases. With the model from the issue, the generated migration has Sqlite:Autoincrement on EF 9.0.9 and 10.0.0, but it is missing on 8.0.8 and 8.0.31. On 9.0+ the column's property mappings come out with the principal key first, so SqliteAnnotationProvider.For(IColumn) reads the right property. It looks like this was fixed as a side effect in 9.0, so it could probably be closed, unless an 8.0 servicing fix is wanted.

    Note

    Drafted with AI assistance (Claude Code) and reviewed by me.

  7. cincuranet commented on Oct 8, 2026

    @cincuranet
    Contributor

    Thanks @mauri0686 for letting us know. At the moment I don't see a need for backporting, but if anybody has a strong reason, let us know and we'll reconsider.

  8. removed this from the Backlog milestone on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions