How to access the database directly from my model class in an ASP.NET Core project?

Asked

Viewed 275 times

1

In ASP.NET Core Mvc I can access Dbcontext in the Controller through the property _context represented by my class MvcNotaContext see:

private readonly MvcNotaContext _context;

This way I can perform a database search in the controller class:

var nota = await _context.Nota.SingleOrDefaultAsync(m => m.ID == id);

However, I have a business rule in my model that needs to get some data directly from the database to perform the validation, but, I don’t know how I could get an instance of my class MvcNotaContext directly in my model class Nota, and this class requires configuration options DbContextOptions<MvcNotaContext> options to function, being that it is used in the method ConfigureServices in class Startup initialization:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddDbContext<MvcNotaContext>(options => options.UseSqlite("Data Source=MvcNota.db"));
}

My model class:

public class Nota: IValidatableObject
{
    public int ID { get; set; }       
    [Required(ErrorMessage="Titulo não pode ficar vazio.")]
    [DataType(DataType.Text)]
    [Display(Name="Título")]
    public string Titulo { get; set; }
    [Required(ErrorMessage="Conteúdo não pode ficar vazio.")]
    [Display(Name="Conteúdo")]
    [DataType(DataType.MultilineText)]
    public string Conteudo { get; set;}

    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        //Busca dados na base de dados.
        throw new System.NotImplementedException();
    }
}

Access to the bank would occur in the method Validate, respectively.


Question

How can I access the database directly from my model class (model) in an ASP.NET Core Mvc project?

  • I didn’t understand it very well. The Note class is a model or an entity?

  • You can consider as a Model.

  • If it is a model, I can consider that you are using as a Viewmodel next to Razor?

  • In this case it is not a Viewmodel, it is only the Model that represents the note table in my database.

  • It is this class that you use in your Dbset to configure your database?

  • Yes exactly, just this class. The bank is just a table.

Show 1 more comment

2 answers

1

Instantiating a context within your model class (which represents a table in the bank) is not an interesting pattern, the domain’s obligation is only to validate itself, and for that you do not need to do a direct instance with the bank. It is not good practice for a more internal layer like the domain to be coupled with a Work Unit.

If you want to compare a value previously entered in the database with a new object, do the query earlier on your chosen layer (recommend doing this on a service layer) and pass it as an argument to your validation class, something like:

var minhaNotaConsultadaDoBanco = await _context.Nota.SingleOrDefaultAsync(m => m.ID == id);

Now in your model:

IEnumerable<ValidationResult> IValidatableObject.Validate(Nota minhaNotaConsultadaDoBanco)
{
    //Exemplo:
    if(this.Titulo != minhaNotaConsultadaDoBanco.Titulo) { ... }
}

If you want to insert a whole new object and double check, you can use the instance itself to call the validation method.

IEnumerable<ValidationResult> IValidatableObject.Validate()
{
    //Exemplo:
    if(this.Titulo != string.Empty) { ... }
}

Calling for:

minhaNotaConsultadaDoBanco.Validate();

1


Just create an instance of the context in this method, exactly as you would any other object

IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext vCtx)
{
    var optBuilder = new DbContextOptionsBuilder<MvcNotaContext>();
    optBuilder.UseSqlite("Data Source=MvcNota.db");
    var context = new MvcNotaContext(optBuilder.Options);
}

Note: I changed the parameter name just to shorten the code.

For this, obviously, you need to make sure that there is a builder of MvcNotaContext which receives an instance of DbContextOptions<T> as a parameter.

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.