Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

Ошибка при вставке новой записи в базу данных через Entity Framework при наличии начальных данных

#c_sharp #postgresql #entity_framework_core


Генерируется база данных с начальными данными. 

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
        modelBuilder.Entity().HasData(
        new Chair[]
        {
            new Chair {Id = 1, Name = "ПМИ" },
            new Chair {Id = 2, Name = "АСОИУ" },
            new Chair {Id = 3, Name = "ИЯ" },
            new Chair {Id = 4, Name = "СИБ" }
        });

        base.OnModelCreating(modelBuilder);

        modelBuilder.ApplyConfiguration(new ChairConfiguration());
    }
}

public class ChairConfiguration : IEntityTypeConfiguration
{
    public void Configure(EntityTypeBuilder builder)
    {
        builder.HasKey(c => c.Id);
        builder.Property(c => c.Name).IsRequired();
    }
}


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

private int GetChairIndex(string chairName)
{
        using (ApplicationContext db = new ApplicationContext())
        {
            if (db.Chairs.Where(c => c.Name == chairName).ToList().Count() == 0)
            {
                var chair = new Chair(chairName);
                db.Chairs.Add(chair);
                db.SaveChanges();
            }
            return db.Chairs.Where(c => c.Name == chairName).Single().Id;
        }
}


На этом этапе выскакивает исключение из-за повторения ключа (Id). Причем при первом
запуске происходит попытка новой записи присвоить Id = 1, при каждом следующем запуске
Id увеличивается каким-то магическим образом. В итоге, на пятой попытке происходит
успешное добавление. Почему Entity Framework сразу не может понять, какой Id нужно
присвоить новой записи?

Класс Chair:

public class Chair
{
    public int Id { get; set; }
    public string Name { get; set; }

    public List Rooms { get; set; }
    public List Disciplines { get; set; }
    public List Groups { get; set; }

    public Chair()
    {
        Rooms = new List();
        Disciplines = new List();
        Groups = new List();
    }

    public Chair(int id, string name)
    {
        Id = id;
        Name = name;
        Rooms = new List();
        Disciplines = new List();
        Groups = new List();
    }

    public Chair(string name)
    {
        Name = name;
        Rooms = new List();
        Disciplines = new List();
        Groups = new List();
    }

    public override bool Equals(object obj)
    {
        if (obj.GetType() != this.GetType())
        {
            return false;
        }

        Chair c = (Chair)obj;
        return (this.Id == c.Id && this.Name == c.Name);
    }
}

    


Ответы

Ответ 1



Решение проблемы оказалось интересным и спорным, указано оно здесь: https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/367 Предлагается два способа: Вставлять начальные данные с отрицательными индексами; modelBuilder.Entity().HasData( new Chair[] { new Chair {Id = -1, Name = "ПМИ" }, new Chair {Id = -2, Name = "АСОИУ" }, new Chair {Id = -3, Name = "ИЯ" }, new Chair {Id = -4, Name = "СИБ" } }); При инициализации базы данных начинать индексацию с определенного значения. В моем случае с 5, так как 4 записи уже вставлены. modelBuilder.HasSequence("ChairsIds") .StartsAt(5); modelBuilder.Entity() .Property(c => c.Id) .HasDefaultValueSql("nextval('\"ChairsIds\"')");

Комментариев нет:

Отправить комментарий