Persistent Entities

Modeling your persistent entities (classes) is the same experience as most any other modeling tool – you drag the class onto the design surface from the toolbox, name it, and start adding properties. You won’t model operations (methods), though, since our focus is on creating code for Entity Framework. If you want to add operations, you’ll do that in partial classes.

Adding an Entity

With the designer open, find the Entity tool in your toolbox. Click and hold down the left button, then drag it to the design surface.

You should see a new class appear on the design surface:

You can change the width of the entity on the designer to make things more readable. Height is automatic and can’t be changed manually - it will be as tall as needed to show all the properties. But the entity may be collapsed down to its name bar by clicking the chevron at the top right of its display. When collapsed, it may be expanded back to its original size by clicking the chevron again.

You can collapse and expand the Properties and Associations compartments by clicking the small + (or -) icon to the left of their gray title bars.

A quick note about the Associations compartments. You’ll note that they’re divided into Association Sources and Association Targets. This really isn’t a big distinction … it has to do with how you started drawing the association and is an artifact of the Microsoft Modeling SDK. One day (hopefully) they’ll be combined into just Associations, but that will take a refactoring of the inner structure of the designer and is a Big Deal. There’s more about Associations later.

Removing an Entity

To remove an entity, simply select it (from either the design surface or the model explorer) and hit the Delete key. It will be removed from the model completely without confirmation, as will its associations with other classes. If you do this by accident, you can undo it (Ctrl-Z or Edit/Undo from the menu).

If that entity is the superclass (base class) for other entities, you’ll be asked if you want to push its attributes and associations down to those other entities prior to its removal.

Entity Properties

Selecting the entity from either the design surface or the model explorer allows you to edit its various properties:

PropertyDescription
Code Generation
Abstract Boolean. If true, an abstract class will be generated for this entity.
Auto Property Default Boolean. If true, Properties for this class will be created as AutoProperties with just bare getters and setters. Otherwise, they'll have a backing field and code in the getters and setters to move the `value` parameters. In this case, you'll also have partial methods available to modify the results.
Base Class String. The name of the class pointed to by the `Inheritance` link in the designer. You can change it here and the link will change in the designer.</a>.
Concurrency String. Overrides the default concurrency handling strategy. Values are 'Optimistic' and 'None'. See Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application.
Custom Attributes String. Attributes generated in the code for this element - anything here will be generated verbatim into the code in the class definition.
Custom Interfaces String. Any custom interface(s) this entity should implement. If more than one, separate them with commas - anything here will be generated verbatim into the code in the class definition.
DbSet Name String. The name of the DbSet property in the DbContext for this class.
Generate Code Boolean. If true (the default), code will be generated for this class. If false, it is assumed to be referenced from another assembly.
Implement INotifyPropertyChanged Boolean. If true, will generate code for easy implementation of property change notifications.
Name String. The name of this class.
Namespace String. The namespace for this class.
Output Directory String. The project directory for this class's generated file. Overrides the default Entity Output Directory.
Database
Database Schema String. The database schema name for the table that will back this class.
Is Dependent Type Boolean. If true, this type will be generated as a "complex" (EF6) or "owned" (EFCore) type.
Table Name String. The name of the table that will back this class.
Display
Fill Color Color. The color for entity's banner on the design surface.
Visible Boolean. If true, the entity will be visible on the design surface. If false, will be hidden. Can also be toggled via the context menu when the entity is selected.
Documentation
Comment Detail String. XML comment <Remarks> section
Comment Summary String. XML comment <Summary> section

Context Menu

Right-clicking on an entity displays a Visual Studio context menu with some new choices pertinent to that entity.

Menu choiceDescription
Add One submenu choice, Property, adds a property to the entity.
Collapse Available when the entity is fully expanded, this action hides the properties so that only the title is visible.
Expand Available when the entity is fully collapsed, this action shows the properties, revsersing the _Collapse_ action.
Cut, Copy, Paste, Delete You can cut or copy, then paste, classes and enums. The pasted elements will be adjusted so that they don't violate any rules (such as two elements not having the same name), but otherwise the properties will stay the same. If no classes or enums are selected in the designer, the cut and copy options will be disabled. If no classes or enums are in the clipboard, the paste option will be disabled.
Validate Checks the currently selected entity against the validation rules built into the designer. Errors or warnings are displayed in Visual Studio's Error List window. If no element is selected, this validates the design surface itself.
Validate All Checks all model elements against the afore mentioned validation rules. Errors or warnings are displayed in Visual Studio's Error List window.
Hide Selected Elements Hides the currently selected elements on the diagram. Any lines to or from those elements will be hidden as well. This does not remove the entity from the model, only makes it invisible in the diagram. Useful for tidying up a diagram that would otherwise be unreadable due to, for example, a common base class that all other classes inherit from. If no entity is selected, this option will be disabled.
Show Hidden Elements Unhides any elements that were previously hidden, along with their association or inheritance lines. If no elements are hidden, this option will be disabled.
Add properties via Code Displays a dialog that lets you add multiple properties using the designer's custom property syntax. See "Adding properties via code" for more details.
Save as Image Will save the entire diagram as an image. Format choices are BMP, GIF, JPG, PNG, TIFF and WMF.
Expand Selected Elements Expands any selected elements that are collapsed to their headers.
Collapse Selected Elements Collapses any elements down to their headers.
Merge Unidirectional Associations Available when you have two Unidirectional Associations selected that both connect the same classes. Turns them into one Bidirectional Association (the inverse of Split Bidirectional Association, below).
Split Bidirectional Association Available when you have a Bidirectional Association selected. Turns it into two Unidirectional Associations (the inverse of Merge Unidirectional Associations, above.).
Select One of the features of the Visual Studio property editor is the ability to edit properties of multiple items if they share that property. This submenu gives you the ability to select model elements by type so that you can conveniently edit properties of those elements together (e.g., setting the color of multiple classes all at once). If the pertinent element type isn't present in the designer, that option will be disabled.
Select all classes... Select all class elements in the designer
Select all enums... Select all enum elements in the designer
Select all associations... Select all association lines (both unidirectional and bidirectional) in the designer
Select all unidirectional associations...Select all unidirectiional association lines in the designer
Select all bidirectional associations... Select all bidirectional association lines in the designer
Properties Switches focus to the Properties window.

INotifyPropertyChanged

You can optionally implement the standard INotifyPropertyChanged interface, especially useful for data binding in WinForms applications. By changing that property to True (by default it’s False), the standard T4 templates will generate code you can customize by implementing a partial method.

The shape on the diagram will change to have a dashed blue border, helping you immediately see which classes will generate change notification code. Since INotifyPropertyChanged requires a bit of logic, the properties of that class won’t be autoproperties. Each property will be set to AutoProperty = False when Implement INotifyPropertyChanged is set to True; if you set AutoProperty to True while indicating that you want INotifyPropertyChanged code, you’ll get a warning on model validation indicating that said property won’t participate in change notification since it’s an autoproperty.

The generated code for a property will look like the following:

   /// <summary>
   /// Backing field for Foo
   /// </summary>
   protected string _Foo;
   /// <summary>
   /// When provided in a partial class, allows value of _Foo to be changed before setting.
   /// </summary>
   partial void SetFoo(string oldValue, ref string newValue);
   /// <summary>
   /// When provided in a partial class, allows value of _Foo to be changed before returning.
   /// </summary>
   partial void GetFoo(ref string result);

   public string Foo
   {
      get
      {
         string value = _Foo;
         GetFoo(ref value);
         return (_Foo = value);
      }
      set
      {
         string oldValue = _Foo;
         SetFoo(oldValue, ref value);
         if (oldValue != value)
         {
            _Foo = value;
            OnPropertyChanged();
         }
      }
   }

   public virtual event PropertyChangedEventHandler PropertyChanged;

   protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
   {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }

Note that this interface doesn’t give you sufficient detail to know how a property changed, only which property changed; Microsoft never intended it to. Its initial purpose was to support data binding, so it’s an important part of .NET, but you need more info to handle property change notifications outside of a data binding context. You have that in the code that’s generated when you set AutoProperty = False in the model for an entity’s property.

Any generated property with a backing field gives you the chance to do work (log, massage the return value, etc.) in their get and set methods by implementing the corresponding GetXXX and SetXXX partial functions. In those partials, you have access to the old and new values (for the SetXXX method) and can implement whatever logging, etc. you need. Therefore, when tracking changes, the generated OnPropertyChanged method will be used when the .NET Framework finds it appropriate but your work should go in the SetXXX partial method.

Next Step

Properties