0

I am trying to implement the following dynamic tableName using Dependency Injection, but I am getting the error

The type arguments for method DbContext.Set(string) cannot be inferred from the usage

Does anyone have an answer or another suggestion to create dynamic entity names?

var tableName = "Table1";
Type returnType;
switch (tableName)
{
 case "Table1":
   returnType = typeof(Table1EntityType);
   break;
 case "Table2":
   returnType = typeof(Table2EntityType);
   break;
}
var query = _context.Set(returnType) -- error occurs here
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
launchCode
  • 23
  • 5
  • Compare the `DbContext.Set` Method in [EF Core](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext.set) and [EF6](https://learn.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext.set). EF6 has an overload with a `Type` argument, EF Core does not. – Olivier Jacot-Descombes Mar 08 '23 at 16:22
  • I am using the EF Core method – launchCode Mar 08 '23 at 17:00
  • The names are already dynamic. `Set<>()` or `Set` provide access to the entities, they don't map them - unless the type is encountered for the first time. That happens *dynamically* based on the mapping information provided by conventions, attributes or explicit calls in `OnConfiguring`. If you want to use a different table name specify it with `ToTable()` – Panagiotis Kanavos Mar 08 '23 at 17:16
  • What are you trying to do? Why do you want "dynamic" table names? You can already use [ToTable](https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.relationalentitytypebuilderextensions.totable?view=efcore-7.0) or `ToView` if you want to explicitly specify every table name. Or you can [create your own conventions.](https://learn.microsoft.com/en-us/ef/core/modeling/bulk-configuration) – Panagiotis Kanavos Mar 08 '23 at 17:23
  • You can even create and use [multiple models for the same DbContext](https://learn.microsoft.com/en-us/ef/core/modeling/dynamic-model) – Panagiotis Kanavos Mar 08 '23 at 17:25
  • It has nothing to do with DI. Also, even if you retrieve the corresponding `DbSet`, the result type (`object`, `IQueryable`, `IQueryable`) won't be very useful w/o some third party library like DynamicLINQ. – Ivan Stoev Mar 08 '23 at 17:47

1 Answers1

2

EF-Core does not have a Set method with a Type argument. You must use a generic Set method: _context.Set<Table1EntityType>():

The problem is that you will need different types for query. Therefore, you will need to do this in a generic method:

void ExecuteQuery<T>()
{
    DbSet<T> query = _context.Set<T>();
    //TODO: do things with query.
}

The selection then goes like this:

var tableName = "Table1";
switch (tableName)
{
    case "Table1":
        ExecuteQuery<Table1EntityType>();
        break;
    case "Table2":
        ExecuteQuery<Table2EntityType>();
        break;
}

A problem arises, if you want to access properties of these entities. Since the C# compiler has no clues of what properties T has, you must add a type constraint:

void ExecuteQuery<T>() where T : CommonBaseTypeAndOrInterfaces
{
    DbSet<T> query = _context.Set<T>();
    //TODO: do things with query.
}

Now, you can reference properties available in CommonBaseTypeAndOrInterfaces.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • I wonder why such a thing is even needed? `ToTable` can be used to change how each type is mapped. It seems there's even a way [to use different models for the same DbContext](https://learn.microsoft.com/en-us/ef/core/modeling/dynamic-model) – Panagiotis Kanavos Mar 08 '23 at 17:24
  • Actually this is a good alternative. Let me know if you like to retract the duplicate closure. – Ivan Stoev Mar 08 '23 at 17:52
  • Thanks Panagiotis! This worked perfect. Ivan please retract the duplicate closure – launchCode Mar 08 '23 at 21:18