Open Closed

Using Dynamic Table Name with ABP #10654


User avatar
0
punta created

In a part of the application that we are building with ABP Commercial, pages render data dynamically based on a presentation template selected at run time. Those templates target different database tables for data storage. Therefore, our controller uses a Dictionary<TKey, TValue> of Function Delegations to return the table name and/or data. What do you advice on Direct Table access alongside the Repository in ABP.

- v10.3, MVC, SQL Server, Tiered.

Thanks!

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

10 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • Avoid “dynamic table name” access through EF Core repositories. In ABP (and EF Core), a repository is designed around a fixed entity mapping. Switching the underlying table name at runtime typically pushes you outside of EF Core’s normal model mapping and can easily bypass ABP’s cross-cutting features (unit of work boundaries, data filters like soft-delete/multi-tenancy, auditing, etc.) unless you re-implement them carefully.

    • Recommended approach (still repository-based): model the dynamic tables explicitly, then select the repository/service at runtime.

      1. Create a separate DbSet<TEntityX> + mapping for each target table (per template/table).
      2. Create a repository/app service per entity/table.
      3. At runtime (based on the chosen template), route to the correct service/repository (your “dictionary of delegates” idea fits here, but you delegate to typed repositories rather than returning raw table names).
    • If you truly have “same schema, multiple tables” (e.g., PresentationData_1, PresentationData_2, ...), EF Core has a concept that ABP can support in advanced scenarios via the repository’s EntityName (meant for EF Core shared-type entity types). You’d configure multiple named entity mappings in your DbContext and then choose which mapping to use by setting the repository’s entity name before executing operations.

    public class MyAppService : ApplicationService
      {
          private readonly IRepository<PresentationRow, Guid> _repo;
    
          public MyAppService(IRepository<PresentationRow, Guid> repo)
          {
              _repo = repo;
          }
    
          public async Task<List<PresentationRow>> GetRowsAsync(string templateKey)
          {
              _repo.SetEntityName(templateKey); // selects the named mapping configured in EF Core model
              return await _repo.GetListAsync();
          }
      }
    

    This keeps you in the repository/UoW world, but requires correct EF Core model configuration for each named mapping.

    • When direct table access is acceptable in ABP: If the data is not part of your domain model (purely “reporting / template rendering / denormalized read model”), consider implementing a dedicated Dapper-based or raw SQL query service in the Infrastructure layer and keep it read-only. Then you still benefit from ABP’s Unit of Work by ensuring the method runs inside a UoW (default in app services), while not trying to force dynamic tables into EF Core entity mapping.

    • What I would not advise: building SQL by concatenating table names from user input. If you must choose a table dynamically, only allow it from a strict whitelist (your dictionary) and keep the SQL parameterized for values.


    Sources (verified)

    • https://abp.io/docs/latest/framework/data/
    • https://learn.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=data-annotations#shared-type-entity-types
    • https://abp.io/support/questions/10157

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    punta created

    Wonderful! Actually each table has its own repository service and DbSet<>. It is better to make the Repository name dynamic than the Table Name. Let me wait for the Support Staffs to have their experience say!

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    1
    maliming created
    Support Team Fullstack Developer

    Hi punta,

    Thanks! Before we suggest a concrete approach, just two quick questions so we point you to the right pattern:

    1. Do those template-driven tables share the same schema (same columns, just different table names), or does each table have its own different columns?
    2. Is the set of tables fixed (a known number shipped with the app), or are new tables created at runtime (e.g. when a user defines a new template)?

    If you can also drop a small snippet of your current Dictionary<TKey, TValue> of delegates and how the controller uses it, that'd help us match the advice to your real code.

    Thanks!

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    1
    alper created
    Support Team Director

    In your specific request, it would be better if you use ADO.NET and don't use ABP's infrastructure.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    punta created

    Hi Maliming, Alper! To the questions,

    1. Each table has its own different columns, containing different sets of information
    2. The set of tables is quasi fixed, only changing on future versions of the app

    My Progress:- I worked out with the AI's suggestion above and refactored everything. Each table is now backed up by a ViewComponent that injects its repository service. Shaped the client side to deal with the ViewComponents instead. In essence, it is the ViewComponent, (and the repository, as such) that is dynamic than the TableName

    We are safe in ABP Infrastructure now! Resorting to ADO.NET is just COSTLY for future progress.

    Thanks Maliming, for always going deeper with my craving for professionalism. Thanks ALL!

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi punta,

    Great to hear it's working cleanly. When each table has its own different columns, your ViewComponent + per-repository approach is a solid path — different columns means a different entity, and ABP's standard generic repositories handle that well while keeping UoW, audit logs, soft-delete and data filters automatic.

    Alper's ADO.NET suggestion is also a great option, especially for read-only / reporting-style access where you don't need those cross-cutting features. Both routes are widely used in ABP apps — the trade-off is just "stay inside ABP infrastructure" vs "lighter raw access". Your call here makes total sense.

    Side note for completeness: ABP 10.0 added an IRepository.EntityName / SetEntityName(...) API (docs) for a different scenario — multiple tables that share the same schema, where you want a single entity type to point at different tables at runtime (EF Core shared-type entity types under the hood). Not applicable to your case, but worth knowing in case it ever fits a future feature.

    Optional refinement if your template count grows: resolve the right repository through IServiceProvider based on the template key (a small factory/strategy), so ViewComponents stay focused on rendering and the dispatch logic lives in one place. Totally optional — what you have already works.

    Thanks!

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    punta created

    Helpful suggestions! I will explore ABP 10's IRepository.EntityName / SetEntityName(...) API; it looks promising for some special situations. Runtime repository resolution is also a good insight, we haven't considered it at all. It is also promising for future features.

    The ADO.NET approach was the fist one in our arsenal, but we put it aside in favor of the ever-improving cross-cutting concerns of ABP. We afraid of cutting off from the promising future.

    Thanks!

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Great. If you run into any other issues, please feel free to let us know.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    1
    alper created
    Support Team Director

    @punta, when you finish implementing this feature, can you write your experience on our https://abp.io/community/articles page? I think people will be interested in reading your approach.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
  • User Avatar
    0
    punta created

    Welcome, Alper! I hope I will do. I am making something out of the reach of my experience today, but I am halfway through it with a profound help of ABP and the support team!

    Thanks Maliming! I will always do that.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 28, 2026, 11:44
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.