mbdavid / LiteDB

LiteDB - A .NET NoSQL Document Store in a single data file
http://www.litedb.org
MIT License
8.62k stars 1.25k forks source link

LiteDB ASP.NET CORE 2 configuration #1035

Open mhnegrao opened 6 years ago

mhnegrao commented 6 years ago

Hello Mauricio, I am implementing a small application with asp.net.cor 2.0, to test the new technology "Blazor", which is very cool and efficient and I am not succeeding. Are there any additional settings to be used in NET.CORE 2?

tks! Marcelo Henrique

mbdavid commented 6 years ago

Hi @mhnegrao, I heard about this technology but I didn't test yet. Current v4 support .net standard 2 (and are compiled on this version).

I current using v5 (dev version) in a new small app using asp.net core 2.0 (with .net core 2) with no problem. Just copy .dll file into my bin folder and works.

If you can use LiteDB in Blazor, please let me know so I can set an example for the community.

mhnegrao commented 6 years ago

Hi ... I'm going to speak in Portuguese ... to flow better ... rs rs vamos lá: qdo tento acessar o arquivo do banco de dados, parece que a aplicação não consegue criar o arquivo .db. ao a brir as ferramentas do desenvolvedor vejo este erro no console: WASM: [System.Runtime.Serialization.SerializationException] Invalid JSON string, pois não há dados e nem arquivo pra retornar o json. Este é o meu modelo de dados:

public class OrdemServico { public OrdemServico() { GerarDados(); } public int Id { get; set; } public DateTime DataOS { get; set; } public string Descricao { get; set; } public decimal Valor { get; set; } public bool Executada { get; set; } public DateTime ExecutadoEm { get; set; } public List ServicosExewcutados { get; set; } = new List();

    public void GerarDados()
    {
        this.Id = 1;
        this.Descricao = "Teste";
        this.DataOS = DateTime.Now;
        this.Executada = true;
        this.ExecutadoEm = DateTime.Now;
        this.Valor = 1000;
    }

Será que esqueci algo?

mbdavid commented 6 years ago

cara, não vi no teu código a chamado no LiteDB... mas cuida em relação aonde tu quer gerar o arquivo, pois teu usuario precisa ter permissão nesse diretorio.

mhnegrao commented 6 years ago

Olá Maurício...blz? Desculpe a demora mas fiz alguns testes aqui e não consigo gravar dados no arquivo .db.

esta é a classe que utilizo pra abrir o bco de dados:

using LiteDB; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using System.Collections.Generic; using System.IO;

namespace AppDatabase.Server.Repository { public class RepositoryBase : IRepositoryBase where TEntity : class { private readonly IHostingEnvironment _env; private string database = "";

    public RepositoryBase(IHostingEnvironment env)
    {
        _env = env;

        if (string.IsNullOrWhiteSpace(_env.WebRootPath))
        {
            _env.WebRootPath =

System.IO.Path.Combine(Directory.GetCurrentDirectory(), "wwwroot"); }

        var webRoot = _env.WebRootPath;
        database = Path.Combine(webRoot, "MeusDados.db");
    }

    public int Add(TEntity obj)
    {
        using (var db = new LiteDatabase(database))
        {
            var col =

db.GetCollection(typeof(TEntity).FullName); var reg = col.Insert(obj); return reg; } }

    public IEnumerable<TEntity> GetAll()
    {
        using (var db = new LiteDatabase(database))
        {
            var regs =

db.GetCollection(typeof(TEntity).FullName).FindAll(); return regs; } }

    public TEntity GetById(int id)
    {
        using (var db = new LiteDatabase(database))
        {
            var regs =

db.GetCollection(typeof(TEntity).FullName).FindById(id); return regs; } }

    public bool Remove(int id)
    {
        using (var db = new LiteDatabase(database))
        {
            var regs =

db.GetCollection(typeof(TEntity).FullName).Delete(id); return regs; } }

    public bool Update(TEntity obj)
    {
        using (var db = new LiteDatabase(database))
        {
            var regs =

db.GetCollection(typeof(TEntity).FullName).Update(obj); return regs; } }

}

}

Como você pode ver é uma classe genérica. Ela cria o arquivo mas não consigo incluir as coleções.

Esta é a chamada que faço para efetuar as transações no banco que está em um controller, o método GerarDados é pra testar a gravação:

using AppDatabase.Server.Repository; using AppDatabase.Shared.Models; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Threading.Tasks;

namespace AppDatabase.Server.Controllers { [Produces("application/json")] [Route("api/cliente")] public class ClienteController : Controller { private readonly IClienteRepository servico;

    public ClienteController(IClienteRepository _servico)
    {
        servico = _servico;
    }

    [HttpGet]
    [Route("api/cliente/Index")]
    public IActionResult Get()
    {
        var clientes = new List<Cliente>();
        *GerarDados*(clientes);
        return Ok(servico.GetAll());
    }

    private  void GerarDados(List<Cliente> clientes)
    {
        clientes.Add(new Cliente
        {
            Id = 1,
            Nome = "Marcelo",
            Ativo = true,
            DataInclusao = DateTime.Now,
            Email = "teste@email.com"

        });
        servico.Add(clientes[0]);
    }

    [HttpGet("{id}")]
    public IActionResult Get(int id)
    {
        return Ok(servico.GetById(id));
    }

    [HttpPost]
    public async Task<IActionResult> Create([FromBody]Cliente cliente)
    {
        servico.Add(cliente);

        return Ok(cliente);
    }

    [HttpPut]
    public async Task<IActionResult> Edit([FromBody]Cliente cliente)
    {
        servico.Update(cliente);

        return Ok(servico);
    }

    [HttpDelete]
    public async Task<IActionResult> Delete([FromBody]Cliente cliente)
    {
        var id = cliente.Id;

        servico.Remove(id);

        return Ok(cliente);
    }
}

}

E aqui a chamada na view:

@view razor@ @page "/associado" @inject HttpClient http @using AppDatabase.Shared.Models

Associados

@if (clientes == null) {

Carregando...

} else {

Novo Cliente

<div>
    <table>
        <thead>
            <tr>
                <th>Id</th>
                <th>Nome</th>
                <th>Email</th>
                <th>Ativo</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var cliente in clientes)
            {
                <tr>
                    <td>@cliente.Id</td>
                    <td>@cliente.Nome</td>
                    <td>@cliente.Email</td>
                    <td>@cliente.Ativo</td>
                    <td>
                        <a href="/clientes/edit/@cliente.Id" class="btn

btn-primary">Editar <a href="/clientes/details/@cliente.Id" class="btn btn-default">Detalhes <a href="/clientes/delete/@cliente.Id" class="btn btn-danger">Excluir }

    </table>
</div>

}

@functions{

Cliente[] clientes;
protected override async Task OnInitAsync()
{
    clientes = await http.GetJsonAsync<Cliente[]>("/api/cliente/index");
}

}

Onde será que estou errando, pois o arquivo é criado mas nada é gravado?

Em sex, 20 de jul de 2018 às 20:37, Mauricio David notifications@github.com escreveu:

cara, não vi no teu código a chamado no LiteDB... mas cuida em relação aonde tu quer gerar o arquivo, pois teu usuario precisa ter permissão nesse diretorio.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mbdavid/LiteDB/issues/1035#issuecomment-406751747, or mute the thread https://github.com/notifications/unsubscribe-auth/AIZJHxRgJn3Z4rdy0urUFC-N-3K8IiImks5uImnOgaJpZM4VW75c .

-- Marcelo Henrique

Análise e Desenvolvimento de Sistemas

Fone (11)97416.2872

mbdavid commented 6 years ago

de cara vejo 2 problemas:

1) tu tá gravando o banco no wwwroot. Tens permissão neste diretorio? geralmente não se tem pq essa é a area publica.... nao deveria ter acesso externo.

2) se tu abre/fecha o banco de dados não pode quere retornar um IEnumerable.... pois antes de chamar o primeiro registro tu ja fechou o banco

    public IEnumerable<TEntity> GetAll()
    {
        using (var db = new LiteDatabase(database))
        {
            var regs =

db.GetCollection(typeof(TEntity).FullName).FindAll(); return regs; } }

Se tu quer retornar todos os dados e depois fechar o banco, precisa usar um "ToArray()" ou "ToList()" depois do FindAll()

Tu chegou a tentar abrir o banco com a ferramenta shell pra ver se tem algum registro la?

mhnegrao commented 6 years ago

Sim... abri o banco e não tinha nada...nenhuma coleção... só banco vazio. Agora pedindo uma ajuda: Em Blazor existem 3 projetos criados inicialmente no modo hosted:

proj.client proj.server proj.shared

e efetuando os testes verifiquei que não estou conseguindo gerar o arquivo corretamente. No caso desta aplicação, wwwroot, onde está o banco está no projeto proj.server que é o que faz as requisições no server (esta pasta eu criei manualmente pra testar). Exite a pasta wwwroot em proj.client que é o início da aplicação cliente e é criada por padrão. Vou efetuar as alterações que vc me indicou. Agora vai a pergunta: qual a melhor maneira para eu criar o arquivo no projeto proj.server, que é onde o repositório de dados está? O asp.net core tem algumas particularidades que talvez eu não esteja observando, já que o banco irá ficar na web.

mhnegrao commented 6 years ago

Se eu conseguir solucionar estes probleminhas, eu passo para vc em detalhes a configuração apropriada para se usar com Blazor

AngelMunoz commented 4 years ago

Hello there, I don't speak Portuguese but from what I pick up from the bits of the conversation (I speak Spanish) LiteDB is unlikely to work on WASM based projects (blazor, uno wasm) since LiteDB needs to write to disk (which is unavailable in websites). LiteDB, however should be able to work just fine on a asp.net core project (the server side) as long as the server application has access to the directory the database is located on