Базовые данные Entity Framework Core с идентификацией 0 - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь добавить начальные данные в мою модель, используя .HasData, чтобы заполнить мою базу данных. Я использую идентификатор 0 в своей модели данных для сопоставления с неизвестным в каждой таблице.

При попытке запустить приложение после добавления этого я получаю следующую ошибку:

Начальный объект для типа объекта 'DboTable' не может быть добавлен, потому что не указано значение для требуемого свойства 'Id'.

Я предположил, что EFCore принудительно устанавливает значение null, поскольку целое число 0 эквивалентно нулю, но когда я пытаюсь вызвать синтаксический анализ целого числа, он по-прежнему выдает ту же ошибку.

На данный момент я не уверен, как подойти к этому, любой совет будет оценен.

фрагмент из DbContext.cs

...
entity.HasData(new DboTable()
{
    Id = 0,               // integer
    Label = "UNKNOWN",    // string
    ...
});
...

Ответы [ 2 ]

0 голосов
/ 19 июня 2019

Я создал небольшой "хак" для обхода ограничения значения 0 PK после того, как я пересмотрел код EF Core , и нашел эту строку кода.

Вот мой код расширения:

using System;
using System.Linq;
using System.Collections.Generic;

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;

namespace EntityFrameworkCore.CustomMigration
{
    public static class CustomModelBuilder
    {
        public static bool IsSignedInteger(this Type type)
           => type == typeof(int)
              || type == typeof(long)
              || type == typeof(short)
              || type == typeof(sbyte);

        public static void Seed<T>(this ModelBuilder modelBuilder, IEnumerable<T> data) where T : class
        {
            var entnty = modelBuilder.Entity<T>();

            var pk = entnty.Metadata
                .GetProperties()
                .FirstOrDefault(property => 
                    property.RequiresValueGenerator() 
                    && property.IsPrimaryKey()
                    && property.ClrType.IsSignedInteger()
                    && property.ClrType.IsDefaultValue(0)
                );
            if (pk != null)
            {
                entnty.Property(pk.Name).ValueGeneratedNever();
                entnty.HasData(data);
                entnty.Property(pk.Name).UseSqlServerIdentityColumn();
            }
            else
            {
                entnty.HasData(data);
            }          
        }
    }
}

И вы можете использовать это следующим образом в OnModelCreating методе:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Seed(new List<Tenant> {
        new Tenant() {TenantID = 0 , Name = string.Empty},
        new Tenant() {TenantID = 1 , Name = "test"}
        //....
        );

    //....
}
0 голосов
/ 16 января 2019

Оказывается, что EF Core 2.1 не поддерживает значение PK равное 0.

К сожалению, любые начальные данные, пытающиеся использовать значение 0 для PK, должны будут выполнить миграцию с пользовательским SQL, чтобы вставить свои записи PK 0.

см .: https://github.com/aspnet/EntityFrameworkCore/issues/12399

...