Search code examples
c#entity-frameworkinterceptor

How to get table name from IDbCommandInterceptor in EntityFramework


I have an Interceptor.

public class EfQueryLogsInterceptor : IDbCommandInterceptor
{
    public void ReaderExecuted(DbCommand command,
         DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
         //string tableName = ???
    }
}

I want to get the table name in the ReaderExecuted method.

How can I do it?


Solution

  • MetadataWorkspace of the context has a lot of useful information:

    public void ReaderExecuted(DbCommand command,
                               DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        // It's taken form https://romiller.com/2014/04/08/ef6-1-mapping-between-types-tables/
        var context = interceptionContext.ObjectContexts.First();
        var metadata = context.MetadataWorkspace;
        var entityTypes = metadata.GetItems<EntityType>(DataSpace.OSpace);
        foreach (var entityType in entityTypes)
        {
            var entitySet = metadata
                            .GetItems<EntityContainer>(DataSpace.CSpace)
                            .Single()
                            .EntitySets
                            .Single(s => s.ElementType.Name == entityType.Name);
            var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
                                  .Single()
                                  .EntitySetMappings
                                  .Single(s => s.EntitySet == entitySet);
            var table = mapping
                        .EntityTypeMappings.Single()
                        .Fragments.Single()
                        .StoreEntitySet;
            var tableName = (string)table.MetadataProperties["Table"].Value ?? table.Name;
    
            //TODO: Use tableName
        }
    }