0

My Problem is this A have a API controler And creating a Single method delete to data from X DbSet properties but the don't have the same Generic paramether. My result is to somehow pass a System.Type to Generic paramether. And my Question is some way to do it?

    var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;

I need to do something like (I know this can't work)

    var table = TableInfo.GetValue(_context) as DbSet<TableInfo.GetType>;

My full code

    [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;
    }

For end sorry about my English. And thanks for all answers :)

Pavel B.
  • 843
  • 1
  • 7
  • 17
  • How do you expect to get static type information from something that is only known at runtime? – InBetween Mar 02 '18 at 16:35
  • I don't see where anything depends on the generic type, so why do you need to cast it as that type? Perhaps you could implement an interface on your `DbSet` that exposes the properties you want regardless of what `T` is, and cast `table` as that. – Scott Hannen Mar 02 '18 at 16:37
  • I neet it becose i neet to get id and if i dont cast it i cant to get Id. I can try "Dynamic" but it can't work i thing – Pavel B. Mar 02 '18 at 16:42
  • Possible duplicate of [How do you call a generic method if you only know the type parameter at runtime?](https://stackoverflow.com/questions/10433007/how-do-you-call-a-generic-method-if-you-only-know-the-type-parameter-at-runtime) – DLCross Mar 02 '18 at 16:43
  • I tryed Interface But its alwais return null becose of this "as". And thank DLCross – Pavel B. Mar 02 '18 at 16:46
  • @DLCross he's not trying to call a generic method, he's trying to cast an object to a generic type. – InBetween Mar 02 '18 at 16:49
  • @InBetween, yes, you are absolutely right: I was going to say that you would still use reflection in a similar fashion, but that 'var' is still not going to work. I should have read the question more carefully. – DLCross Mar 02 '18 at 16:51

1 Answers1

1

var table = TableInfo.GetValue(_context) as DbSet<[here i need pass it]>;

You can't do that, you have no compile time information on what type you need, how do you expect to leverage it before the code is even running?

If you really want compile time type information of table you either know the generic type at compile time or you cover all possible execution paths considering all potential generic types your method must handle (horrendous, don't do that).

Using an interface won't work either. A hypothetical IIdEntity and a cast along the lines table as DbSet<IIdEntity> will never work because:

  1. Type variance is only allowed in interfaces and delegates, DbSet is not an interface.
  2. Even if you use IDbSet<TEntity>, this interface is invariant in TEntity so the following will always fail:

    class User: IIdEntity { ... }
    object o = someDbEntityOfUser;
    var db = o as IDbSet<IIdEntity> //will always be null.
    

The best options you have with your current setup are:

  1. Keep using reflection; use it to inspect the Id property of the entities.
  2. Use dynamic and simply let the runtime resolve the Id call.
InBetween
  • 32,319
  • 3
  • 50
  • 90