EF Core InMemory с использованием базы данных SQLite - внешний ключ при удалении установлен в значение null Проблема - PullRequest
0 голосов
/ 29 марта 2020

My. NET В проекте Core 3.1 используется как первичный DBContext с SQL сервером, так и у меня есть вторичный DBContext, который использует базу данных SQLite в памяти. Причина, по которой БД в памяти обеспечивает более быстрый доступ для чтения. Моя БД в памяти настроена таким образом, что когда в SQL происходит операция CRUD, БД в памяти также обновляется.

Проблема в том, что я не могу заставить ".OnDelete (DeleteBehavior.SetNull)" работать с базой данных SQLite в памяти. Оба DBContexts и связанный с ними Fluent API оба настроены одинаково. Я выбрал опцию SQLite in-memory на том основании, что она должна предоставлять реляционную БД, то есть каскадное удаление и устанавливать нулевые функции.

В этом примере у меня есть две таблицы: InMemTcpServer & InMemStrings

Каждый объект InMemStrings имеет ссылку на внешний ключ к объекту InMemTcpServer (отношение один ко многим), поэтому, когда InMemTcpServer удален, я хочу, чтобы поле внешнего ключа в InMemStrings было установлено на ноль.

При тестировании всего этого используя DBContext с моего SQL сервера, все работает нормально, в среде памяти что-то не так.

InMemStrings Модель:

public class InMemStrings
{
    public int Id { get; set; } // Primary Key
    public string Name { get; set; }
    public string ConnectorType { get; set; }
    public int? TcpServerId { get; set; }
    public InMemTcpServer InMemTcpServer { get; set; }

}

InTcpServer Модель:

public class InMemTcpServer
{
    public int Id { get; set; } // Primary Key
    public string Name { get; set; }
    public string DataFlow { get; set; }
    public string Encoding { get; set; }
    public string IpAddress { get; set; }
    public int PortNumber { get; set; }
    public string Location { get; set; }
    public bool AutoStart { get; set; }
    public ICollection<InMemStrings> InMemStrings { get; set; }
}

InMemoryDbContext:

public class InMemDbAContext : DbContext
{
    public InMemDbAContext()
    {
    }

    public InMemDbAContext(DbContextOptions<InMemDbAContext> options) : base(options)
    {
    }

    public DbSet<InMemTcpServer> InMemTcpServers { get; set; }
    public DbSet<InMemImage> InMemImages { get; set; }
    public DbSet<InMemSound> InMemSounds { get; set; }
    public DbSet<InMemSpeech> InMemSpeech { get; set; }
    public DbSet<InMemStrings> InMemStrings { get; set; }

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

        // If a tcpserver is deleted, set foreign key field in related Strings DB Table to null
        modelBuilder.Entity<InMemStrings>()
            .HasOne(p => p.InMemTcpServer)
            .WithMany(b => b.InMemStrings)
            .OnDelete(DeleteBehavior.SetNull);
    }
}

Метод, который удаляет InMemTcpServer:

var inMemTcpServer = _inMemDbAContext.InMemTcpServers.Where(i => i.Id == job.Id).FirstOrDefault();

if (inMemTcpServer != null)
{                                    
   _inMemDbAContext.InMemTcpServers.Remove(inMemTcpServer);
   _inMemDbAContext.SaveChanges();
}

Как только вышеупомянутый InMemTcpServer был удален, я ожидаю, что его соответствующий внешний ключ в другом Для таблицы нужно установить значение NULL, так же, как это делается в собственном DBContext, который использует SQL Server.

Из того, что я прочитал, кажется, что использование SQLite для оперативной памяти должно поддерживать использование реляционных таблиц в EF Core?

...