61

If you look here you will notice that this guy is showing the Entity Model Diagrams, I would like to know how I can create an Entity Model Diagram from my EntityFramework code first classes.

It just gets frustrating trying to remember how everything links together just by looking at the code.

Callum Linington
  • 14,213
  • 12
  • 75
  • 154
  • That has a page not found... It is the Entity Data Model Browser, I have no idea how to get it, and to engineer a model from my classes – Callum Linington Sep 06 '13 at 12:49
  • Something like this [ADO.NET Entity Data Model Designer](http://msdn.microsoft.com/en-us/library/vstudio/cc716685(v=vs.100).aspx) ? – johnnynotsolucky Sep 06 '13 at 12:56

4 Answers4

65

With the Entity Frameworks Power Tools installed you can right-click the context in your solution view, click on "Entity Framework", then select "View Entity Data Model".

This will create a neat diagram from your classes.

tinonetic
  • 7,751
  • 11
  • 54
  • 79
Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
  • That was exactly what I was looking for, couldn't quite remember the name! – Callum Linington Sep 07 '13 at 11:33
  • 2
    Unfortunately this extension is not supported in VS2015 anymore. :( – Efrain Mar 31 '16 at 13:26
  • 2
    You can get an updated version of Entity Framework power tools 4 beta for visual studios 2010 - 2015 at GitHub (https://github.com/lastlink/EFPowerToolsExample). I would also suggest to Dennis Traub to consider updating his answer's link. That could prevent us from regular digging. Anyway, Dennnis, thanks a lot for poiting it out this great tool. – Julio Nobre Mar 02 '17 at 17:18
  • Ok... I'm going to guess that the link in the answer (https://marketplace.visualstudio.com/items?itemName=ErikEJ.EntityFramework6PowerToolsCommunityEdition) installs something that doesn't work with the latest EF Core stuff in the latest VS 2019 (v16.4.5), because when I try to View Entity Data Model (Read-Only) it complains that it can't find a constructable class that derives from DbContext, despite the fact that the file contains `public class ApplicationDbContext : IdentityDbContext {…}` – Bob.at.Indigo.Health Mar 04 '20 at 22:32
  • Tried this, but it did not help, unfortunately: https://stackoverflow.com/questions/18470595/a-constructible-type-deriving-from-dbcontext-could-not-be-found-in-the-selected – tobbenb3 Sep 30 '20 at 12:05
53

An Entity Data Model Diagram is just a visual display of an EDMX file. In order to get such a diagram from a Code-First model you must create an EDMX file from it:

using System.Data.Entity.Infrastructure; // namespace for the EdmxWriter class

using (var ctx = new MyContext())
{
    using (var writer = new XmlTextWriter(@"c:\Model.edmx", Encoding.Default))
    {
        EdmxWriter.WriteEdmx(ctx, writer);
    }
}

This code creates a file Model.edmx that you can open in Visual Studio. It will display the model diagram. The EDMX file is a snapshot of your current Code-First model. When you change the model in code you must create a new EDMX file to reflect those changes in the diagram.

Slauma
  • 175,098
  • 59
  • 401
  • 420
  • 1
    Simple and clean! Entity Framework Power Tools would be my first choice, but they are painful to use for complex projects. – StefanG Feb 04 '15 at 12:01
  • 1
    Don't forget to run Visual Studio as administrator so that you could able to create the .edmx file – Ehsan88 Aug 25 '15 at 11:55
6

In addition to Slauma his answer. If you want to be able to adjust the layout of the diagram and you dont want to redo this every time again after creation, you can copy the Diagram node from the previously EDMX file into the new EDMX file:

        string sPath = @"c:\Development\{0}";
        try
        {
            File.Copy(String.Format(sPath, "Model.edmx"), String.Format(sPath, "ModelTemplate.edmx"));
            File.Delete(String.Format(sPath, "Model.edmx"));
        }
        catch (Exception)
        {

            //no worry, file not found issues
        }

        using (var ctx = new ShopID.Models.ShopIDDb())
        {
            using (var writer = new XmlTextWriter(String.Format(sPath, "Model.edmx"), Encoding.Default))
            {
                EdmxWriter.WriteEdmx(ctx, writer);
            }
        }

        XmlDocument oldModel = new XmlDocument();
        oldModel.Load(String.Format(sPath, "ModelTemplate.edmx"));
        XmlDocument newModel = new XmlDocument();
        newModel.Load(String.Format(sPath, "Model.edmx"));

        var nsmgr = new XmlNamespaceManager(newModel.NameTable);
        nsmgr.AddNamespace("diagram", "http://schemas.microsoft.com/ado/2009/11/edmx");
        XmlNode node = oldModel.SelectSingleNode("//diagram:Diagrams", nsmgr).ChildNodes[0];
        XmlNode newNode = newModel.SelectSingleNode("//diagram:Diagrams", nsmgr);
        XmlNode importNode = newNode.OwnerDocument.ImportNode(node, true);
        newModel.ImportNode(importNode, true);
        newNode.AppendChild(importNode);
        newModel.Save(String.Format(sPath, "Model.edmx"));
        File.Delete(String.Format(sPath, "ModelTemplate.edmx"));

//Updated model is ready to be opened with Visual Studio

Jaap
  • 61
  • 1
  • Used this for a bit and then realised that any entities/associations added to the model are not drawn in the updated one, as the corresponding diagram nodes are missing. Here's what I do now: – Ian Jul 26 '17 at 11:43
0

To retain layout from a previous EF Power Tools generated diagram, this will carry over the Entities positions and colours etc. that exist in the new one, and leave any additions as is. Otherwise you don't see the new entities in the diagram.

    static void CopyLayout(string srcFile, string destFile)
    {
        var oldModel = XDocument.Load(srcFile);
        var newModel = XDocument.Load(destFile);

        XNamespace edmxNs = "http://schemas.microsoft.com/ado/2009/11/edmx";
        // find all entity shapes
        var oldEts = oldModel.Root.Descendants(edmxNs + "EntityTypeShape").Select(ets => ets).ToList();
        var newEts = newModel.Root.Descendants(edmxNs + "EntityTypeShape").Select(ets => ets).ToList();
        // replace any matching new with old
        foreach (var newEt in newEts)
        {
            var match = oldEts.SingleOrDefault(ot => ot.Attribute(@"EntityType").Value ==
                                                     newEt.Attribute(@"EntityType").Value);
            if (match != null)
                newEt.ReplaceAttributes(match.Attributes());
        }
        newModel.Save(destFile);
    }
Ian
  • 101
  • 3
  • 5