Получить идентификатор для новой записи из существующей последовательности в EF Core и npgsql - PullRequest
0 голосов
/ 10 сентября 2018

Я поместил существующую базу данных в проект и настроил свойства сущности, насколько мне известно.

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

Я использую базу данных PostgreSQL, мой конструктор моделей выглядит так:

modelBuilder.ForNpgsqlUseIdentityColumns();
modelBuilder.HasSequence<int>("contact_id_seq");
modelBuilder.Entity<Contact>(entity =>
        {
            entity.HasKey(e => e.Id);

            entity.ToTable("contact");

            entity.Property(e => e.Id)
                .HasColumnName("id")
                .HasDefaultValueSql("nextval('contact_id_seq')")
                .ValueGeneratedOnAdd();

            [...]

        }

Модель:

public partial class Contact {
    [DisplayName("DBID")]
    public int Id { get; set; }

    [...]
}

Диспетчер вызова:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("<model member>")] Contact contact) {
    (ModelState.IsValid) {
        _context.Add(contact);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(contact);
}

Последовательность внутри базы данных postgreSQL выглядит следующим образом:

-- Sequence: contact_id_seq

-- DROP SEQUENCE contact_id_seq;

CREATE SEQUENCE contact_id_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 12758
  CACHE 1;
ALTER TABLE contact_id_seq
  OWNER TO postgres;

Ошибка:

Npgsql.PostgresException (0x80004005): 23502: null value in column "id" violates not-null constraint 
at Npgsql.NpgsqlConnector.<>c__DisplayClass161_0.<<ReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

Обновление: Я также попробовал select nextval('contact_id_seq') и дополнительные аннотации модели, такие как [Key] или [DatabaseGenerated(DatabaseGeneratedOption.Identity)], но безрезультатно. У меня заканчиваются решения, может быть, я должен просто запросить следующее значение с помощью команды sql ...

Update2: В качестве обходного пути я сейчас делаю необработанный SQL-запрос для значения последовательности:

using (DbCommand cmd = _context.Database.GetDbConnection().CreateCommand()) 
{
    cmd.CommandText = "select nextval('contact_id_seq')";
    _context.Database.OpenConnection();
    DbDataReader reader = cmd.ExecuteReader();
    reader.Read();
    newID = (int)reader.GetValue(0);
    _context.Database.CloseConnection();
}

Я использовал информацию отсюда: https://www.npgsql.org/efcore/value-generation.html

Я пытался найти в Google проблему с подходящими ключевыми словами, но кроме связанного, я не смог найти тот, который использовал мое созвездие.

Microsoft.EntityFrameworkCore.Tools 2.1.0

Npgsql.EntityFrameworkCore.PostgreSQL 2.1.0

PostgreSQL 9.6.10

...