Yordi.EntityMultiSQL 1.2.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package Yordi.EntityMultiSQL --version 1.2.3
                    
NuGet\Install-Package Yordi.EntityMultiSQL -Version 1.2.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Yordi.EntityMultiSQL" Version="1.2.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Yordi.EntityMultiSQL" Version="1.2.3" />
                    
Directory.Packages.props
<PackageReference Include="Yordi.EntityMultiSQL" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Yordi.EntityMultiSQL --version 1.2.3
                    
#r "nuget: Yordi.EntityMultiSQL, 1.2.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Yordi.EntityMultiSQL@1.2.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Yordi.EntityMultiSQL&version=1.2.3
                    
Install as a Cake Addin
#tool nuget:?package=Yordi.EntityMultiSQL&version=1.2.3
                    
Install as a Cake Tool

Yordi.EntityMultiSQL

Framework .NET para mapeamento POCO → SQL, CRUD assíncrono, criação/atualização de tabelas e gerenciamento automático de índices (incluindo índices parciais).

⚠️ Posicionamento atual da biblioteca

Importante: a biblioteca não é mais especializada para MySQL.
Apesar do nome MultiSQL, o design atual está orientado a um núcleo multibanco, com foco prático em SQLite e MySQL no runtime de conexão.


Principais recursos

  • CRUD assíncrono com repositórios genéricos
  • Criação e atualização de tabelas por reflexão de POCOs
  • Gerenciamento automático de índices:
    • simples
    • compostos
    • parciais (WHERE)
  • Suporte a atributos de mapeamento (Key, Autoincrement, etc.)
  • Tratamento de concorrência no SQLite com:
    • BusyTimeout
    • WAL mode (PRAGMA journal_mode=WAL)
    • lock de escrita coordenado por semáforo
  • Checkpoint manual para cenários de pausa/continuidade de serviço
  • Encerramento gracioso de conexão SQLite com checkpoint WAL no shutdown

Novidades da linha 1.2.x

A evolução recente consolidou o comportamento de concorrência e encerramento no SQLite.

1) SQLiteConnectionManager

Gerencia o ciclo de vida da conexão SQLite:

  • criação de conexão com BusyTimeout automático
  • habilitação idempotente de WAL mode
  • conexão por operação: cada chamada a CriarConexao() retorna uma nova SQLiteConnection; o pool nativo do SQLite reaproveita a conexão nativa — instanciar o objeto .NET é barato
  • serialização de escrita com SemaphoreSlim estático
  • checkpoint manual sem alterar journal_mode:
    • CheckpointAsync (via CheckpointSQLiteAsync): PRAGMA wal_checkpoint(TRUNCATE) + PRAGMA shrink_memory
  • dois caminhos de encerramento:
    • EncerrarAsync (via Dispose/DisposeAsync): aguarda lock de escrita, PRAGMA wal_checkpoint(TRUNCATE), PRAGMA shrink_memory, fechamento e limpeza de pool
    • LiberarLocksAsync (via LiberarLocksSQLiteAsync): limpeza de pool, checkpoint, PRAGMA journal_mode=DELETE (remove arquivos -wal/-shm), segundo checkpoint, PRAGMA shrink_memory, fechamento e limpeza de pool

2) IBDConexao com controle operacional

Além de abrir conexão, agora expõe métodos explícitos para lock/shutdown:

  • AguardarLockEscritaAsync(...)
  • LiberarLockEscrita()
  • ResetarConexao()
  • CheckpointSQLiteAsync()
  • LiberarLocksSQLiteAsync()

3) BDConexao mais resiliente

  • delega o comportamento SQLite ao SQLiteConnectionManager
  • conexão por operação para SQLite: cada chamada a ObterConexaoAsync cria uma nova SQLiteConnection — elimina ObjectDisposedException causado por compartilhamento de instância entre threads
  • mantém reset de conexão para recuperação em cenários de lock/estado inválido
  • suporta descarte síncrono e assíncrono (Dispose / DisposeAsync)

Requisitos

  • .NET 8.0
  • Yordi.Tools (compatível com a versão definida no projeto)
  • System.Data.SQLite
  • MySql.Data

Instalação

dotnet add package Yordi.EntityMultiSQL

Uso rápido

1) Configuração (DBConfig)

Exemplo típico para SQLite:

var config = new DBConfig
{
    TipoDB = TipoDB.SQLite,
    Local = @".\\Database",
    Database = "Topcon.Service.db",
    TryReconnect = 3,
    SecondsWaitToTry = 1,
    UsarSQLiteWALMode = true
};

IBDConexao conexao = new BDConexao(config);

2) Repositório

public class MeuRepositorio : RepositorioGenerico<MinhaEntidade>
{
    public MeuRepositorio(IBDConexao bd) : base(bd) { }
}

3) Entidade POCO

[POCOtoDB(Tipo = POCOType.CADASTRO)]
public class MinhaEntidade
{
    [Autoincrement]
    public int Auto { get; set; }

    [Key]
    public string Codigo { get; set; } = string.Empty;
}

Ciclo de vida em Windows Service (OnPause / OnContinue / OnStop)

Exemplo recomendado para SQLite:

// OnPause: checkpoint leve, mantém WAL e operação para continuar depois
await conexao.CheckpointSQLiteAsync();

// OnContinue: retoma processamento normal

// OnStop/OnShutdown: encerramento forte + dispose
await conexao.LiberarLocksSQLiteAsync();
await conexao.DisposeAsync();

CheckpointSQLiteAsync não altera journal_mode, portanto é apropriado para pausa temporária. LiberarLocksSQLiteAsync aplica PRAGMA journal_mode=DELETE, indicado para encerramento definitivo.


Índices automáticos e parciais

A biblioteca mantém suporte a índices definidos nas entidades via IPOCOIndexes e classe Chave (Yordi.Tools), inclusive com cláusula WHERE.

Para detalhes completos:

  • INDEX_MANAGEMENT_DOCUMENTATION.md

Shutdown gracioso (SQLite / WAL)

Em Host, Worker Service ou Windows Service, finalize explicitamente a conexão no encerramento:

await conexao.LiberarLocksSQLiteAsync();
await conexao.DisposeAsync();

LiberarLocksSQLiteAsync aplica PRAGMA journal_mode=DELETE, o que faz o SQLite remover os arquivos auxiliares (-wal, -shm). DisposeAsync executa o checkpoint WAL e limpa os pools de conexão.


Evolução (resumo)

  • 1.2.3
    • Fix: verificação de existência da coluna no DataRow antes de acessar — evita ArgumentException silenciado para propriedades sem coluna correspondente
    • Fix: tipo valor não-anulável (int, bool, etc.) com valor nulo no banco mantém o default do tipo em vez de lançar ArgumentException
    • Fix: conversão UTC→Local para campos de auditoria (DataInclusao/DataAlteracao) reativada e corrigida — respeita DateTime.Kind para evitar dupla conversão quando o driver já retorna Local (comportamento padrão do System.Data.SQLite)
    • Fix: long→int com checked cast para detectar overflow; bool tratado via comparação com 0/1 (padrão SQLite)
    • Fix: condição invertida em Datas() que impedia lançar ArgumentException quando T não herdava de CommonColumns
    • Novo: suporte a DateOnly, TimeOnly, TimeSpan e DateTimeOffset no mapeamento — converte a partir de string, DateTime, TimeSpan e valores numéricos Unix timestamp (long/int) para total compatibilidade com SQLite
    • Novo: cache estático de PropertyInfo[] por tipo (ConcurrentDictionary) — evita reflexão repetida em grandes volumes de dados
  • 1.2.2
    • atualização e verificação de dependências: MySql.Data 9.7.0, SQLitePCLRaw 3.0.3, System.Data.SQLite 2.0.3, Yordi.Tools 1.0.19
  • 1.2.1
    • adicionado CheckpointSQLiteAsync para checkpoint manual sem alterar journal_mode
    • documentação de uso para ciclos OnPause/OnContinue/OnStop em serviços
  • 1.2.0
    • consolidação dos recursos de concorrência SQLite
    • melhorias para cenários de database is locked
    • gerenciamento de WAL e locks no ciclo de vida da conexão
  • 1.1.4
    • ajustes de dependência (Chave em Yordi.Tools)
  • 1.1.3
    • DEPRECATED (não utilizar)

Contribuição

Contribuições são bem-vindas via issues e pull requests.

Licença

MIT.

Autor

Leopoldo Yordi (leoyordi).

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.3.2 152 8/3/2026
1.3.1 101 8/3/2026
1.2.5 127 5/12/2026
1.2.4 113 5/12/2026
1.2.3 106 5/12/2026
1.2.2 115 5/10/2026
1.2.1 105 5/6/2026
1.2.0 139 3/16/2026
1.2.0-rc3 125 2/3/2026
1.2.0-rc2 131 12/31/2025
1.2.0-rc1 209 12/24/2025
1.1.4 469 12/8/2025
1.1.3 798 12/8/2025 1.1.3 is deprecated.
1.1.2 280 9/21/2025
1.1.1 236 6/25/2025
1.1.0 235 6/25/2025
1.0.4 242 3/17/2025
1.0.3 210 2/25/2025
1.0.1 198 2/15/2025
1.0.0 229 2/14/2025 1.0.0 is deprecated because it has critical bugs.

v1.2.3: Correções e melhorias no mapeamento POCO→objeto (método Objeto):
- Fix: verificação de existência da coluna no DataRow antes de acessar (evita ArgumentException silenciado).
- Fix: tipo valor não-anulável com valor nulo no banco mantém o default do tipo, sem tentar SetValue(null).
- Fix: conversão UTC→Local para campos de auditoria (DataInclusao/DataAlteracao) reativada e corrigida — respeita DateTime.Kind para evitar dupla conversão quando o driver já retorna Local.
- Fix: long→int com checked cast para detectar overflow de valores SQLite; bool tratado via comparação com 0/1 (padrão SQLite).
- Fix: condição invertida em Datas() que impedia lançar ArgumentException quando T não herdava de CommonColumns.
- Novo: suporte a conversão de DateOnly, TimeOnly, TimeSpan e DateTimeOffset a partir de string, DateTime, TimeSpan e valores numéricos Unix timestamp (long/int) para compatibilidade com SQLite.
- Novo: cache estático de PropertyInfo[] por tipo (ConcurrentDictionary) para evitar reflexão repetida em grandes volumes.
v1.2.2: Atualização e verificação de dependências: MySql.Data 9.7.0, SQLitePCLRaw.bundle_e_sqlite3 3.0.3, SQLitePCLRaw.core 3.0.3, System.Data.SQLite 2.0.3, Yordi.Tools 1.0.19.
v1.2.1: Adicionado CheckpointSQLiteAsync para checkpoint manual (sem alterar journal_mode), com orientação para uso em ciclos de serviço (OnPause/OnContinue) e manutenção da liberação forte para OnStop/OnShutdown.
v1.2.0: Lançamento oficial da versão 1.2.0.
v1.2.0-rc3: Acréscimo de recursos para lidar com 'database is locked' no SQLite.
v1.2.0-rc2: Correção de bugs menores. Atualização da biblioteca Yordi.Tools para v1.0.16.
v1.2.0-rc1: Release Candidate 1.
v1.1.4: Atualização de dependências - Classe Chave movida para Yordi.Tools v1.0.14. IMPORTANTE: version 1.1.3 is DEPRECATED.
v1.1.3: [DEPRECATED] Não utilizar - problemas de dependência.