Creating Models with the Visual Designer
The LightSpeed visual designer integrates into Visual Studio 2008, Visual Studio 2010 and Visual Studio 2012.
To create a model with the visual designer, add a LightSpeed Model item to your Visual Studio project. The easiest way to do this is to right‑click the project in Solution Explorer and choose Add > New Item, then choose LightSpeed Model in the Add Item dialog. You can find it in the Data tab as well as the main list.
The designer is initially blank (except for some links for users who want help getting started). You can either create entities in the designer using the Toolbox, or create entities from your existing database tables.
To create an entity in the designer, open the Visual Studio Toolbox and drag the Entity from the Toolbox onto the design surface.
Initially, the new entity will be called Entity1. To change this, just type the new name while the entity is selected.
The Visual Studio Properties window shows more options for configuring the entity:
For example, you can also edit the entity name through the Name box in the Properties window.
Many of the settings in the Properties window are things you’ll only need to think about as you start building up your model. For example, you’ll use the Persistence options if you need to customise the way the entity is stored in the database. This book covers the various options under the relevant chapters. You can also get an idea of what each option does by looking at the description area at the bottom of the Properties window.
One option that’s important for all models is the Identity Type option. Every entity in LightSpeed has an Id, a unique identifier that allows LightSpeed to tell it apart from other entities of the same type. The default identity type is Int32 – the .NET Int32 type, equivalent to the C# int type. If you expect to create a huge number of entities, you’ll probably want to change this to Int64 (C# long). Some users prefer GUID Ids to numeric Ids, so you can also choose the Guid identity type. (The String identity type is usually used only for natural keys in legacy databases: see Working with Legacy Databases if you think you need string keys.)
To add properties to the entity, right‑click it and choose Add New Entity Property.
A shortcut for this is to hit the Insert key when the entity (or an existing property of the entity) is selected. This will add a new entity after the entity that is currently selected.
You can edit the name of the new property by typing:
The default data type for newly created properties is String. Use the Properties grid to change this if necessary:
You can also enter the type in front of the property name, just like declaring a C# field:
When you save your model, LightSpeed generates .NET classes for each of the entities you have defined. These classes are stored in a generated code file with the same name as the model file and a .cs or .vb file extension. You can open this file in Visual Studio to view the entity class code, but you cannot edit the file – if you do, your changes will be overwritten next time LightSpeed regenerates the code. Always make changes through the designer, never in the generated code file.
The generated entity classes are partial classes. This means you can extend them through your own partial class files, for example to add domain methods. Again, always do this through a partial class file, never by editing the generated code.
As mentioned above, each entity in the designer is a .NET class. All entity classes inherit from the LightSpeed Entity<TId> class, which in turn inherits from the Entity base class. The Basic Operations chapter describes how to load, create, modify and delete entities, and the Getting Started book (linked on the Start menu) and screencast (linked from the designer surface and the Get Started command) provide walkthroughs.
The properties you specify on the designer become properties of the class. You can get or set these properties using normal C# or Visual Basic syntax:
Customer customer = /* get a customer – see Basic Operations chapter */;
As discussed above, a domain model is realised in at least two ways: an object model and a relational database schema. The object model is automatically generated when you save the visual model file. You can also have LightSpeed generate the database schema for you.
To do this, you must first tell LightSpeed what kind of database you are using, and provide the connection string to that database. To do this, click on the model background and enter these settings into the Properties window.
(You only need to do this once – LightSpeed remembers the settings for future updates.)
Now, if you right-click on the model background, you will see an Update Database option:
Click on this and LightSpeed will compare your model to the database and display a list of changes that need to be made to the database. (If the database doesn’t already exist, LightSpeed may be able to create it for you. This depends on the database provider. For providers where LightSpeed can’t create databases, you’ll need to use a suitable database administration tool to create a blank database.)
You can use Update Database to keep your database schema in sync with your model as your model evolves. Update Database does not regenerate tables each time, but instead applies only the changes it detects between the model and the database schema. Hence, it does not modify or delete existing data (except when it detects that, for example, a column needs to be deleted because it is no longer in the model) so it is safe to use with databases containing test data. It is not, however, a production tool! If you want to capture the changes that Update Database detects, so that you can run them against production environments in a controlled way, see the Database Migrations chapter.
You can exclude an action proposed by Update Database by clearing the relevant checkbox. However, because the difference between the model and database remains, LightSpeed will continue to suggest the change until you reconcile the difference.
Update Database allows you to very rapidly iterate your model. Because it is non‑destructive it is easy to tweak the model incrementally until you are happy with it, try out experimental changes, and so on. For more information about this, see Workflows for Rapid Application Development in the chapter Working with Models in the Visual Designer.
The previous sections assumed that you were creating a new model from scratch, and could begin from the domain model design. It may be that your database already exists, and you want to create a model that corresponds to that existing database schema.
To do this, open the Visual Studio Server Explorer, and expand the database you want to model. (If the database isn’t already in Server Explorer, right-click Data Connections and choose Add Connection to add it.) Select the tables you want to include in your model, and drag them onto the design surface.
When you drag tables from a database, you don’t need to specify the entity name and identity type, or the property names and data types, because these are already set up in the database through the tables and columns. LightSpeed works them out from the database schema.
You can make changes to an entity which has been dragged from Server Explorer just as if you had created it using the Toolbox. For example, you can add new properties by choosing Add New Entity Property or using the Insert key. Of course, this means your entity class is now out of sync with your database, but you can use Update Database to fix that. Update Database works out what changes need to be made and applies them to the database for you.
(In this case, you don’t need to have entered a database provider or connection string the way you did when you started from scratch. LightSpeed works them out from the Server Explorer connection.)
If you want to keep the database as the master source for the model, you can use the Update From Source command instead of Update Database.
Update From Source updates the model to be in sync with the database schema. For example, if you have added a column to a table, Update From Source will add a corresponding property to the entity. Note however that Update From Source only looks at existing entities – this is because a database may contain a huge number of tables not related to the task at hand, and you don’t want these cluttering up the model.
Like Update Database, Update From Source is non‑destructive. For example, if you’ve applied validations or renamed a property (provided you have kept the database column mapping), Update From Source will not overwrite your changes. Of course, if you have changed something that takes the model out of sync with the database, such as changing a property data type, then Update From Source will propose to change it back.
As with Update Database, you can exclude an action proposed by Update From Source by clearing the relevant checkbox, but the action will continue to appear until you reconcile the difference.
LightSpeed supports three kinds of associations: one‑to‑many, one‑to‑one and many‑to‑many.
To create a one‑to‑many association, select the One To Many Association connector in the toolbox, and drag an arrow from the ‘one’ end to the ‘many’ end. For example, if a Customer can have multiple Orders, drag the arrow from Customer to Order.
This creates a property at each end of the association. The ‘one’ end has a collection property, representing the collection of associated ‘child’ entities. The ‘many’ end has a backreference property, representing the ‘parent’ entity. In the example above, Customer has an Orders collection property, and Order has a Customer backreference property. LightSpeed guesses names for these properties based on the entity names. You can edit these names by clicking on them in the diagram, or by selecting the arrow and editing the Collection Name and Backreference Name options in the Properties window.
In code, you work with these properties in the same way as with other collection and object properties:
// Using a collection property
A one‑to‑many association also results in a foreign key property. You can’t customise the name or type of this property, because the name is always the backreference name followed by “Id” – for example, CustomerId – and the type is always the identity type of the parent entity. You may sometimes use the foreign key property in your code, especially in serialisation scenarios, and you can customise its mapping to a database column if required (see Controlling the Database Mapping).
A one‑to‑one association is added in much the same way as a one‑to‑many association, except that it has a source and a target instead of a collection and a backreference.
When you use Update Database to create or update database tables, LightSpeed creates a foreign key column in the appropriate table to represent each association.
If you are creating entities from database tables, then LightSpeed creates associations for you based on foreign keys in the database. Consequently, when you drag a table onto the designer, any columns that are foreign keys do not appear as properties – instead, they appear implicitly as the foreign keys of the inferred associations.
Many‑to‑many associations work in a slightly different way to one-to-many or one‑to‑one associations, because they have to be stored in a different way at the relational level. Instead of a simple foreign key, a many‑to‑many association requires a whole table of foreign keys. This table is variously known as a join table, relationship table or through table. Each entry in the through table represents a pair of associated entities; and an entity can participate in multiple pairs.
A many‑to‑many association is modelled in LightSpeed using a through association, so named because it goes ‘through’ an intermediate entity. The intermediate entity corresponds to the through table and is known as the through entity.
To create a through association, select the Through Association connector in the toolbox, and drag an arrow between the entities you want to associate. You must then select the arrow and specify the through entity. The easiest way to do this is to enter a name in the Auto Through Entity box: LightSpeed will create a minimal through entity for you. (For more information about this and how to get finer control over the through entity, see the chapter Working with Models in the Visual Designer.)
A through association results in two collection properties, one at each end. LightSpeed guesses names for these based on the names of the entities. When you use a through association from code, you’ll usually uses these two collections, in just the same way as normal collections – you can iterate over them, add items to them, remove items from them, and so on.
Using a through association
// iterating over the through association
The through association also results in a through entity class and one‑to‑many associations from the ‘main’ entity classes to the through entity class (which in turn manifest in code as collection, backreference and foreign key properties). These are visible in code, but most applications don’t need to use them. You’ll typically only work with through entities for diagnostics, or if you want to associate further data with each pairing in the many‑to‑many (for example, a ‘tagged by’ field).
When you use Update Database to create or update database tables, LightSpeed creates any required through tables, with suitable foreign keys.
Your model can include documentation for entities, properties, one-to-many associations and stored procedures. Documentation will be emitted as XML documentation comments which are displayed in Intellisense or can be built into a Help file using a tool such as Sandcastle.
To view or edit documentation, right click on the designer and choose Documentation. The LightSpeed Documentation window is displayed. Depending on the selected entity, this will display different fields—typically Summary, Remarks and Additional. Enter your documentation into these fields. The Documentation window tracks your selection in the same way as the Properties window.
For most fields, LightSpeed will generate the required documentation tags (e.g. <summary>) for you. However, for fields marked (XML), you must include the container tags yourself. This allows you to generate elements such as <exception> which are not directly represented in LightSpeed.
LightSpeed supports documentation for most common model elements, but not for some less frequently used elements. Please visit the support forum (linked from the Start menu) if you need to document a model element which does not currently support documentation.