Как избежать использования ключевого слова AUTOINCREMENT с EFC и SQLite? - PullRequest
0 голосов
/ 24 сентября 2018

AUTOINCREMENT обычно не нужно использовать в SQLite. Даже без этого ключевого слова автоматически генерируемые идентификаторы работают.

Однако при использовании Entity Framework целочисленный первичный ключ объявляется как AUTOINCREMENT.Core (по состоянию на 2.1.3) и SQLite.Есть ли способ избежать этого?

Я попытался добавить атрибут [DatabaseGenerated(DatabaseGeneratedOption.None)] в свойство первичного ключа объекта, но это вообще отключает автоматическую генерацию ключа, и мне приходится устанавливать его вручную для каждой вставки.В противном случае EFC попытается вставить с явным Id = 0.

Так что мне нужно, чтобы он обрабатывался как база данных, сгенерированная при вставке, я просто хотел бы избежать ненужного ключевого слова AUTOINCREMENT.Есть ли способ сделать это?

Редактировать

Вот пример кода C #:

using System;
using Microsoft.EntityFrameworkCore;

namespace Experiments
{
    public class Entity
    {
        public long Id { get; set; }

        public string Text { get; set; }
    }

    public class Context : DbContext
    {
        public DbSet<Entity> Entities { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=temp.sqlite");
        }
    }

    public static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        private static void Main()
        {
            using (var context = new Context())
            {
                context.Database.EnsureCreated();
            }
        }
    }
}

Это создаст базу данных, которая выглядит следующим образом, если смотреть с БДБраузер для SQLite:

enter image description here

Я бы не хотел, чтобы первичный ключ был объявлен как AUTOINCREMENT, который также создает таблицу sqlite_sequence.SQLite может генерировать ключи без этого ключевого слова, и делает это проще и быстрее.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Насколько я могу судить, проблема вызвана следующим кодом в текущем SqliteMigrationsAnnotationProvider классе:

if (property.ValueGenerated == ValueGenerated.OnAdd
    && property.ClrType.UnwrapNullableType().IsInteger()
    && !HasConverter(property))
{

    yield return new Annotation(SqliteAnnotationNames.Autoincrement, true);
}

, который вызывает SqliteMigrationsSqlGenerator класс до включает AUTOINCREMENT.

Я не знаю, почему это так, я бы предположил, что это оставшаяся ошибка, но вам лучше спросить в их системе отслеживания проблем.

Глядя на код, похоже, что установка конвертера поддельных значений предотвратит это и может использоваться как временное решение:

modelBuilder.Entity<Entity>()
    .Property(e => e.Id)
    .HasConversion(v => v, v => v);
0 голосов
/ 24 сентября 2018

Определен класс модели, как показано ниже.Таким образом, вы не будете сопоставлять столбец Id и использовать другой столбец в качестве PK.

[NotMapped]
public override int Id
{
    get
    {
        return PKColumn;
    }
    set
    {
        PKColumn = value;
    }
}

[Key]
public virtual int PKColumn { get; set; }
...