动态 select 来自 DbContext 的 DbSet 成员?
Dynamically select DbSet member from DbContext?
我想创建一个可以由具体 OData 控制器继承的动态 OData 控制器。为此,我需要从我的 DbContext 中找到 select 正确的 DbSet 并在控制器中使用它。但是,我不知道如何用 C# 写下来。这是我试过的:
背景是数据库中有两张结构完全相同的表,但要求将它们分开,因为它们包含不同类型的数据。所以我想要一个动态的 FileData 控制器,我可以在其中将所需的类型传递给并基本上在 FileData 控制器中对所有内容进行一次编码。
数据库上下文
public class DS2DbContext : DbContext
{
public DbSet<DocumentFileData> DocumentFileData { get; set; }
public DbSet<WatermarkFileData> WatermarkFileData { get; set; }
public DS2DbContext(DbContextOptions<DS2DbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
控制器
public class FileDataController<T> : ODataController
{
private readonly DS2DbContext _context;
private readonly ILogger<FileDataController<T>> _logger;
// --------------------------------------------------
public FileDataController(DS2DbContext dbContext, ILogger<FileDataController<T>> logger)
{
_logger = logger;
_context = dbContext;
}
public DbSet<T> DB()
// Error CS0452:
// The type 'T' must be a reference type in order to use it as parameter
// 'TEntity' in the generic type or method 'DbSet<TEntity>'
{
PropertyInfo pi = _context.GetType().GetProperty(nameof(T));
MethodInfo mi = pi.GetGetMethod();
return (DbSet<T>)mi.Invoke(this, null); // error CS0452
}
[EnableQuery(PageSize = 15)]
public IQueryable<T> Get()
{
//return _db.FileData;
return DB();
}
[EnableQuery]
public SingleResult<WatermarkFileData> Get([FromODataUri] Guid ID)
{
//var result = _db.FileData.Where(c => c.ID == ID);
var result = DB().Where(c => c.ID == ID);
return SingleResult.Create(result);
}
}
无需自定义方法,使用 DbContext.Set<T>
方法。
要修复编译错误,您需要向控制器添加通用约束 class,如下所示:
public class FileDataController<T> : ODataController where T : class
注意 where T : class
,这是必需的,因为 DbSet
class 本身具有 where TEntity : class
约束
我想创建一个可以由具体 OData 控制器继承的动态 OData 控制器。为此,我需要从我的 DbContext 中找到 select 正确的 DbSet 并在控制器中使用它。但是,我不知道如何用 C# 写下来。这是我试过的:
背景是数据库中有两张结构完全相同的表,但要求将它们分开,因为它们包含不同类型的数据。所以我想要一个动态的 FileData 控制器,我可以在其中将所需的类型传递给并基本上在 FileData 控制器中对所有内容进行一次编码。
数据库上下文
public class DS2DbContext : DbContext
{
public DbSet<DocumentFileData> DocumentFileData { get; set; }
public DbSet<WatermarkFileData> WatermarkFileData { get; set; }
public DS2DbContext(DbContextOptions<DS2DbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
控制器
public class FileDataController<T> : ODataController
{
private readonly DS2DbContext _context;
private readonly ILogger<FileDataController<T>> _logger;
// --------------------------------------------------
public FileDataController(DS2DbContext dbContext, ILogger<FileDataController<T>> logger)
{
_logger = logger;
_context = dbContext;
}
public DbSet<T> DB()
// Error CS0452:
// The type 'T' must be a reference type in order to use it as parameter
// 'TEntity' in the generic type or method 'DbSet<TEntity>'
{
PropertyInfo pi = _context.GetType().GetProperty(nameof(T));
MethodInfo mi = pi.GetGetMethod();
return (DbSet<T>)mi.Invoke(this, null); // error CS0452
}
[EnableQuery(PageSize = 15)]
public IQueryable<T> Get()
{
//return _db.FileData;
return DB();
}
[EnableQuery]
public SingleResult<WatermarkFileData> Get([FromODataUri] Guid ID)
{
//var result = _db.FileData.Where(c => c.ID == ID);
var result = DB().Where(c => c.ID == ID);
return SingleResult.Create(result);
}
}
无需自定义方法,使用 DbContext.Set<T>
方法。
要修复编译错误,您需要向控制器添加通用约束 class,如下所示:
public class FileDataController<T> : ODataController where T : class
注意 where T : class
,这是必需的,因为 DbSet
class 本身具有 where TEntity : class
约束