首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以将DbSet与泛型类型一起使用?

是否可以将DbSet与泛型类型一起使用?
EN

Stack Overflow用户
提问于 2021-05-20 16:45:08
回答 1查看 158关注 0票数 0

我一直在为康复中心设计一个平台。我们需要存储约会信息,每个约会都有多个考勤表,每个考勤表都是数据库中的一个表。所以,我有一个Appointments表和一个表为每个出席表。我需要恢复某一任命的数据和在该特定任命中使用的所有出勤表。问题是,每次预约的出勤表数量不同,因为医疗专业可以根据任命填写不同的出勤表。

所有考勤表单的名称都具有相同的前缀,因此我可以这样做:

代码语言:javascript
复制
var formsNamesQuery = from table in _context.GetType().GetProperties()
                      where table.Name.StartsWith("Form") 
                      select table.Name;

var formsNames = formsNamesQuery.ToList();

这样做,现在我只有考勤表的名称。为了查询每个表,我执行以下操作:

代码语言:javascript
复制
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();
}

但我不知道如何向DbContext说我正在搜索的表单的类型。我一直在寻找,但我没有找到解决办法。我看到了这个question,它引导我找到了这个方法

代码语言:javascript
复制
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;
}

我这样叫它:

代码语言:javascript
复制
var formResults = RestoreFormInfo(form.GetType(), formName, pacientID, appointmentID);

使用这个方法,我可以传递表单类型,但是我得到了这个错误

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-25 16:27:39

我要这样解决这个问题:

代码语言:javascript
复制
foreach (var formName in formsNames)
{
     var form = typeof(DbContext).GetProperty(formName).PropertyType;
     
     var method = typeof(AppointmentsController).GetMethod("RestoreFormInfo");

     // Because the form variable is a DbSet<FormType>, I needed to get the
     // FormType from the GenericTypeArguments array.
     var genericMethod = method.MakeGenericMethod(form.GenericTypeArguments[0]);

     var formResults = await (Task<object>) genericMethod.Invoke(this, new object[] { formName, pacientID, appointmentID });
}

现在,RestoreFormInfo方法如下所示:

代码语言:javascript
复制
public async Task<object> RestoreFormInfo<TEntity>(string formName, string pacientID, int AppointmentID) where TEntity : class
{
     var dataSet = _context.Set<TEntity>();
     
     try
     {
          var results = await dataSet.FromSqlRaw(
               $"SELECT * FROM {formName} WHERE PacientID = '{pacientID}' AND AppointmentID = {appointmentID}")
               .AsNoTracking()
               .FirstAsync();
     }
     catch (InvalidOperationException)
     {
          // The expected error is the "InvalidOperationException: Enumerator failed to MoveNextAsync",
          // it means that the FirstAsync didn't find any result.
          return null;
     }
     
     return results;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67624669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档