I've been working on a platform for a rehab center. We need to store the appointments info and each appointment has multiple attendance forms, each attendance form is a table in the database. So, I have the Appointments
table and one table for each attendance form. I need to restore the data of a certain appointment and all the attendance forms used in that particular appointment. The problem is that the number of attendance forms varies for each appointment because a healthcare professional can fill different attendance forms according to the appointment.
The name of all attendance forms has the same prefix, so I can do this:
var formsNamesQuery = from table in _context.GetType().GetProperties()
where table.Name.StartsWith("Form")
select table.Name;
var formsNames = formsNamesQuery.ToList();
Doing this, now I have only the name of the attendance form tables. To query each table, I do this:
foreach (var formName in formsNames)
{
var form = _context.GetType().GetProperty(formName).GetType();
var formResults = _context.Set<FormType>().FromSqlRaw(
$"SELECT * FROM {formName} WHERE PacientID = '{pacientID}' AND AppointmentID = {appointmentID}")
.AsNoTracking()
.FirstAsync();
}
But I don't know how to say to the DbContext
the type of the form I'm searching for. I've been searching a lot, but I didn't find a solution. I saw this question and it led me to this method:
public IList RestoreFormInfo<TEntity>(TEntity entity, string formName, string pacientID, int AppointmentID) where TEntity : class
{
var dataSet = _context.Set<TEntity>();
var results = dataSet.FromSqlRaw(
$"SELECT * FROM {formName} WHERE PacientID = '{pacientID}' AND AppointmentID = {appointmentID}")
.AsNoTracking()
.FirstAsync();
return (IList) results;
}
And I call it like this:
var formResults = RestoreFormInfo(form.GetType(), formName, pacientID, appointmentID);
With this method, I can pass the form type, but I get this error:
InvalidOperationException: Cannot create a DbSet for 'Type' because this type is not included in the model for the context.
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.get_EntityType()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.CheckState()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.get_EntityQueryable()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.System.Linq.IQueryable.get_Provider()
Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw<TEntity>(DbSet<TEntity> source, string sql, object[] parameters)
SigCER.Controllers.AppointmentsController.RestoreFormInfo<TEntity>(TEntity entity, string formName, string pacientID, int appointmentID) in AppointmentsController.cs
var results = dataSet.FromSqlRaw(
SigCER.Controllers.AppointmentsController.AttendanceForms(int appointmentID, string pacientID) in AppointmentsController.cs
var formResults = RestoreFormInfo(form.GetType(), formName, pacientID, appointmentID);
lambda_method(Closure , object )
Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable+Awaiter.GetResult()
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask<IActionResult> actionResultValueTask)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)