泛型接口/实现类/方法返回不同的结果集



我正在使用EF开发.Net核心应用程序,大约有20个表/实体。我必须从中获取数据,每个表都有不同的列。假设表是表1、表2、表3……表20。

  1. 接口:创建一个泛型接口有一些方法和一个例子
public interface IDataService<TEntity>
{
public Task<List<TEntity>> GeDataAsync();
}  
  1. 实现:现在我的实现类如下所示,它基本上是从表1中填充数据
public class Table1Service : IDataService<Table1>
{
private readonly ModelContext _context;

public Table1Service(ModelContext context)
{
_context = context;
}
public async Task<List<Table1>> GeDataAsync();
{

return await _context.Table1s().ToListAsync();
}
  1. 控制器:
public class DataController : Controller
{
private IDataService<Table1> _table1Service;
public DataController(IDataService<Table1> table1Service; )
{
_table1Service = table1Service;

}
[HttpGet("GeDataAsync")]
public async Task<IActionResult> GeDataAsync( string tableName; )
{
var tableEnum = Enum.Parse<TableNames>(tableName); //;
switch (tableEnum)
{
case TableNames.Table1:
return Ok(ApiResult<List<Table1>>.Success200(await _table1Service.GeDataAsync()));
break;

}
// ...................................
}

}
jquery的Ajax调用

这种方法至少有两个问题:

  1. 我必须再创建19个实现类(Table2Service、Table2Service…Table20Service(来从它们各自的类中填充数据。类别(表2、表3……表20(
  2. 我不能传递那么多IDataService、DataService。。控制器类的构造函数中的DataService。未来可能会有更多

我要找的是:

  1. 一个通用接口
  2. 一个通用实现类,它为所有这20个表提供数据
  3. 一个控制器和方法GeDataAsync((,它根据ajax传递的表名返回表结果

非常感谢您的帮助。

要获得完全通用的解决方案,您需要进行一些更改。

  1. 您需要更改接口-使方法通用,而不是接口:
public interface IDataService
{
public Task<List<TEntity>> GeDataAsync<TEntity>() where TEntity : class;
}

这里需要通用约束,EF才能工作。

  1. 更改您的服务实现:
public class GenericService : IDataService
{
private readonly ModelContext _context;

public GenericService(ModelContext context)
{
_context = context;
}

public async Task<List<TEntity>> GeDataAsync<TEntity>() where TEntity : class =>                
await _context.Set<TEntity>().ToListAsync();
}

您可以在上下文中调用Set()方法来指向EF以使用该实体类型。

  1. 现在您的控制器只需要GenericService(IDataService(的1个依赖项:
public class DataController : Controller
{
private IDataService _dataService;
public DataController(IDataService dataService)
{
_dataService = dataService;
}
}
  1. 剩下的就是某种映射,将请求中的表名映射到调用服务方法的正确实体类型。据我所知;特别的";方法仅通过表名来指向EF以处理某些表,因此您将在控制器中获得类似的GetDataAsync()操作实现

要使映射通用,可以使用反射:

  1. 您可以在控制器操作中获得表名
  2. 有了表名,您应该通过一些映射(如Dictionary<string, Type>(或检查表(实体(类的属性来获得要使用的实体的类型。因此,您应该有一个Type变量,它是要使用的实体类型
  3. 您可以在上下文类上找到Set()方法,通过调用MakeGenericMethod()并设置第二步中得到的实体类型使其通用
  4. 现在,您可以使用yourMethodInfo.Invoke()调用通用的Set()方法

如果使用反射,我建议将表名传递给服务方法,并在服务中完成所有这些工作。

最新更新