Как мне получить все классы DbContext и все DbSet под каждым DbContext - PullRequest
0 голосов
/ 31 декабря 2018

Я работаю над большим проектом с 50+ DbContext и 100+ DbSet под каждым DbContext.

Каждый DbContext обрабатывается отдельной командой, и они добавляют /удаление DbSet в соответствии с их требованиями / изменениями.

Из централизованного представления / отчета я хотел бы видеть все DbContext классы и все DbSet под каждым DbContext в родительском дочернем представлении, для управления базой данных.

Как получить все DbContext классы и все DbSet для каждого DbContext, в запросе LinQ или в функции C #?

Используяследующий код, я получил список DbSets под DbContext, но в моем случае, может быть и новый DbContext.

var metadata = ((IObjectContextAdapter)dbContext).ObjectContext.MetadataWorkspace;

var tables = metadata.GetItemCollection(DataSpace.SSpace)
                     .GetItems<EntityContainer>()
                     .Single()
                     .BaseEntitySets
                     .OfType<EntitySet>()
                     .Where(s => !s.MetadataProperties.Contains("Type")
                                 || s.MetadataProperties["Type"].ToString() == "Tables");

foreach (var table in tables)
{
    var tableName = table.MetadataProperties.Contains("Table")
                    && table.MetadataProperties["Table"].Value != null
                    ? table.MetadataProperties["Table"].Value.ToString()
                    : table.Name;

    var tableSchema = table.MetadataProperties["Schema"].Value.ToString();

    Console.WriteLine(tableSchema + "." + tableName);
}

Поэтому я ищу динамический список, который должен включатьновые DbContexts тоже.

Как получить все классы DbContext и все DbSet под каждым DbContex, в запросе LinQ или в функции ac #.

1 Ответ

0 голосов
/ 31 декабря 2018

Как насчет чего-то вроде:

public Dictionary<Type, List<object>> FindDbContextsInAssemblies()
{
   var dbContexts = new Dictionary<Type, List<object>>();

   var assemblies = AppDomain.CurrentDomain.GetAssemblies();

   foreach(var assembly in assemblies)
   {
      foreach(var type in assembly.GetTypes())
      {
         if(type.IsSubclassOf(typeof(DbContext)))
         {
            // Instantiate DbContext:
            var context = type.GetConstructor(Array.Empty<Type>()).Invoke(Array.Empty<object>());

            // Find method to get entities:
            var model = type.GetProperty("Model");
            var searchMethod = model.PropertyType.GetMethod("GetEntityTypes");

            // Get registered entities:
            var entities = searchMethod.Invoke(model.GetValue(context, null), null) as List<object>;

            dbContexts[type] = entities;
         }
      }
   }

   return dbContexts;
}

Не проверял это.Идея состоит в том, чтобы прочесать сборки, найти соответствующие классы и динамически вызвать метод GetEntityTypes () .

...