将 System.Type 传递给通用类型
passing System.Type to generic type
我的问题是这个 A 有一个 API 控制器并创建一个单一方法从 X DbSet 属性中删除数据,但没有相同的通用参数。我的结果是以某种方式将 System.Type 传递给通用参数。我的问题是如何做到这一点?
var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;
我需要做类似的事情(我知道这行不通)
var table = TableInfo.GetValue(_context) as DbSet<TableInfo.GetType>;
我的完整代码
[HttpDelete("{name}/{id}")]
[Route("api/Delete")]
public IActionResult Delete(string name = "Items", int id = 2)
{
PropertyInfo TableInfo = GetValueByName(name);
if (TableInfo == null)
return NotFound("Haaaah");
var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;
if (table == null)
return BadRequest();
var prop = table.SingleOrDefault(p => p.Id == id);
if (prop == null)
return NotFound(prop);
table.Remove(prop);
_context.SaveChanges();
return Ok();
}
public PropertyInfo GetValueByName(string name)
{
Type t = _context.GetType();
List<PropertyInfo> list = new List<PropertyInfo>(t.GetProperties());
foreach(PropertyInfo m in list)
{
if (m.Name == name)
return m;
}
return null;
}
最后对我的英语感到抱歉。
并感谢所有答案:)
var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;
你不能那样做,你没有关于你需要什么类型的编译时信息,你希望如何利用它在代码甚至运行?
如果你真的想要 table
的编译时类型信息,你要么 知道 编译时的泛型类型,要么涵盖所有可能的执行路径,考虑所有潜在的泛型类型你的方法必须处理(太可怕了,不要那样做)。
使用界面也不行。假设的 IIdEntity
和沿线的转换 table as DbSet<IIdEntity>
永远不会起作用,因为:
- 类型变化只允许在接口和委托中使用,
DbSet
不是接口。
即使你使用IDbSet<TEntity>
,这个接口在TEntity
中是不变的所以下面总是会失败:
class User: IIdEntity { ... }
object o = someDbEntityOfUser;
var db = o as IDbSet<IIdEntity> //will always be null.
您当前设置的最佳选择是:
- 继续使用反射;用它来检查实体的
Id
属性。
- 使用
dynamic
并让运行时解析 Id
调用。
我的问题是这个 A 有一个 API 控制器并创建一个单一方法从 X DbSet 属性中删除数据,但没有相同的通用参数。我的结果是以某种方式将 System.Type 传递给通用参数。我的问题是如何做到这一点?
var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;
我需要做类似的事情(我知道这行不通)
var table = TableInfo.GetValue(_context) as DbSet<TableInfo.GetType>;
我的完整代码
[HttpDelete("{name}/{id}")]
[Route("api/Delete")]
public IActionResult Delete(string name = "Items", int id = 2)
{
PropertyInfo TableInfo = GetValueByName(name);
if (TableInfo == null)
return NotFound("Haaaah");
var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;
if (table == null)
return BadRequest();
var prop = table.SingleOrDefault(p => p.Id == id);
if (prop == null)
return NotFound(prop);
table.Remove(prop);
_context.SaveChanges();
return Ok();
}
public PropertyInfo GetValueByName(string name)
{
Type t = _context.GetType();
List<PropertyInfo> list = new List<PropertyInfo>(t.GetProperties());
foreach(PropertyInfo m in list)
{
if (m.Name == name)
return m;
}
return null;
}
最后对我的英语感到抱歉。 并感谢所有答案:)
var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;
你不能那样做,你没有关于你需要什么类型的编译时信息,你希望如何利用它在代码甚至运行?
如果你真的想要 table
的编译时类型信息,你要么 知道 编译时的泛型类型,要么涵盖所有可能的执行路径,考虑所有潜在的泛型类型你的方法必须处理(太可怕了,不要那样做)。
使用界面也不行。假设的 IIdEntity
和沿线的转换 table as DbSet<IIdEntity>
永远不会起作用,因为:
- 类型变化只允许在接口和委托中使用,
DbSet
不是接口。 即使你使用
IDbSet<TEntity>
,这个接口在TEntity
中是不变的所以下面总是会失败:class User: IIdEntity { ... } object o = someDbEntityOfUser; var db = o as IDbSet<IIdEntity> //will always be null.
您当前设置的最佳选择是:
- 继续使用反射;用它来检查实体的
Id
属性。 - 使用
dynamic
并让运行时解析Id
调用。