Retrieving fluent configuration programatically wi

2019-02-26 18:26发布

问题:

I have a DbContext derived class whose member entity classes are configured using Fluent API. I want to retrieve these configurations and relationships programatically. the code to do this is already in place and I am porting it to a T4 template for code generation.

While most of the code generation uses reflection, fluent configuration requires the context class to be instantiated in order to get:

  • ObjectContext
  • EntityObjects
  • EntityContainer
  • EntitySets
  • Etcetera

Since we are not using property attributes, reflection is of no help.

This works fine during runtime, but instatiating the DbContext within a T4 template is causing all sorts of problems. It sometimes crashes VS, gives weird errors, creates a cyclic dependency, etc.

If I debug the T4 template, it does run without errors but the background process locks the project containing the DbContext class and entities. So every time there is a change to the entities, I have to restart VS three times performing different steps. Yuck!

I was wondering if there is a way to retrieve entity metadata/configuration without instantiating the context class. Any guidance would be appreciated.

回答1:

Well, you need to load the context because it needs to call OnModelBuilding(DbModelBuilder) at least once to do it's business; otherwise there is no model to interrogate.

If you want, you can store off the information as XML using EdmxWriter;

    public static string ToEdmx(this System.Data.Entity.DbContext context)
    {
        var sb = new StringBuilder();

        using (var textWriter = new StringWriter(sb))
        using (var xmlWriter = System.Xml.XmlWriter.Create(textWriter, new System.Xml.XmlWriterSettings { Indent = true, IndentChars = "    " }))
        {
            System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(context, xmlWriter);
            textWriter.Flush();
        }

        return sb.ToString();
    }

This will give you an XML document with the data model. You can probably save that to disk in one process, and interrogate that file in your TT file.