Signum Framework Logo
"Open framework that encourages convention over configuration, using C# code,
not XML files, to model at the right level of abstraction and achieve deadlines.
...but also has a full Linq provider, and syncs the schema for you!"
Login
RSS

Search

»



Main
Index
Map
Videos
Download
Source code
Tutorials
Forum
FAQ



Image



PoweredBy

Introduction

Signum Entities is the assembly that contains the basic tools for modelling your business entities.

Designing your entities is the central task when designing an application in Signum Framework, the rest of the application is going to be built around the shape of these business entities. There are many aspects of your application that depend on this shape:

  • Database schema
  • Validation
  • Serialization
  • Big influence on user interface.

Bad News

Every entity has to inherit from some of the base classes in Signum.Entities, so there's no POCO (Plain Old CLR Object) support. Also, there's not a lot of flexibility on how the database is going to look, instead it's just an image of your entities following a standard mapping algorithm.

In the end, that means that you can't use Signum Framework with an existing database, neither with your existing classes. Instead you have to write your entities from scratch and move your data, if any, to the recently created database using a loading program.

So we think that Signum Framework is the best solution for new projects (see FAQ for the reasons), but there are some breaking changes to take into account when moving legacy applications. If you want to be able to access your data quickly by drag and dropping some tables to a designer use LINQ to SQL. If you want to use your existing classes and your existing tables and have a rich and flexible mapping technology, then use NHibernate or Entity Framework.

Good News

So now we have lost half of the audience already and only the ones brave enough to do things the right way are still here. Let's start to work.

The good news is that, ok, Signum Framework needs to be the king of the town, but it's not a bad king:

  • Classes: Signum Entities base classes are just plain classes, with normal field and properties. They only have embedded change tracking through a convenient Set method, and some support for validation by implementing IDataErrorInfo. Nothing extremely clever here.

  • Tables: The tables generated by Signum Entities are very normal also. Just tables, foreign keys, relational tables, indexes. Easy stuff. Also, by having an algorithm and not a human creating the database, you end up with a carefully normalized database with good naming conventions and foreign keys. Also, by having the entities as the only model, adding indexes on fields when appropriate is easier.

Example

People prefer to see the utility of things from the very beginning and follow a top-down approach, so let's start at the end. The next example shows an entity defining a Computer using a lot of the Signum.Entities' available features. If you prefer to start in easy mode go to VideoTutorialBasic.

The example has changed to follow Signum Framework 2.0 style.

    [Serializable]
    public class ComputerDN : Entity
    {
        [UniqueIndex]
        int modelNumber;
        [NumberIsValidator(ComparisonType.GreaterThan, 0)]
        public int ModelNumber        
        {
            get { return modelNumber; }
            set { Set(ref modelNumber, value, ()=>ModelNumber); }
        }

ProcessorDN processor; public ProcessorDN Processor { get { return processor; } set { Set(ref processor, value, ()=>Processor); } } Lite<ComputerBrandDN> brand; public Lite<ComputerBrandDN> Brand { get { return brand; } set { Set(ref brand, value, ()=>Brand); } }

[ImplementedBy(typeof(HardDiskDN), typeof(SolidStateDriveDN))] IDrive drive; public IDrive Drive { get { return drive; } set { Set(ref drive, value, ()=>Drive); } }

MList<MemoryModuleDN> memoryModule; public MList<MemoryModuleDN> MemoryModule { get { return memoryModule; } set { Set(ref memoryModule, value, ()=>MemoryModule); } }

ComputerState computerState; public ComputerState ComputerState { get { return computerState; } set { Set(ref computerState, value, ()=>State); } } }

enum ComputerState { Demanded, OnStock, Shipped, Sold, }

.


Some things to notice:

  • The entity is Serializable. This is not mandatory if you are not going to send the entity but why clip your wings just because of a little attribute?

  • The entity inherits from Entity class. See more about Base Entities.

  • The first field, modelNumber, is just a plain old int field with a UniqueAttribute over it to create an index on the database. See More about Field Attributes

  • The property ModelNumber, as any other, uses Set method to make the assignment. This is useful for Change Tracking.

  • The property ModelNumber has a Validator attribute to enforce that the number has to be bigger than 0. See more about Validation.

  • The Processor field and property have the type ProcessorDN. A foreign key to the ProcessorDN's table will be created in the database.

  • Since ComputerBrandDN is a heavy entity, the developer has used a Lite to make the association to it.

  • There are two kinds of drives nowadays, HardDisk and SolidStateDrive, each one will have its' own table. By using ImplementedBy attribute you get a polymorphic foreign key. See more about this in Inheritance.

  • You can have more than one memory module in a computer. Entities uses MList to model One-to-Many and Many-to-Many relationships.

  • Finally, a computer can be in four states defined in a Enum. Enums don't have the flexibility to change at runtime, but when logic depends on them they can be very convenient. Signum Entities have friction free support for Enums.

Note 1: You will be asking to yourself where this DN thing comes from. It stands for "Dato de Negocio" that means Business Object in Spanish, and since we are a Spanish company we use this convention for entities. This convention, however, has nothing to do with the framework itself and you can use your own, but it's a good idea to have one so we will write the DN postfix in our examples.

On the Database

The following is the database schema for these entities:

Image

As you can see, the table tlComputerDN has been created, also all the tables for the reachable entities. All the tables have Id, ToStr and since they all inherit from the Entity (not just IdentifiableEntity) they also have a Ticks field. See more about Base Entities.

On tlComputerDN table, a ModelNumber column has been created with database type int NOT NULL, we always try to reduce Type mismatch. See more in Field Attributes.

Columns idProcessor and idBrand have foreign keys to tlProcessorDN, tlComputerBrandDN respectively. Both allow null, since in .Net they are reference types and could be null as well. Both are similar since laziness of fields does not affect the schema.

The .Net field Drive has been divided into two columns, idDrive_HardDiskDN and idDrive_SolidStateDriveDN, following the directives of ImplmentedBy attribute. See more about Inheritance.

Finally, notice the ComputerState Enum has his own table as any other entity, and a foreign key has been created. This table already contains the following data.

Image

Note 2: The 'tr' and 'trtl' prefix has been deprecated as the standard configuration for tables and relational tables, but you can restore it or change this in another way by overriding SchemaBuilder.

Note 3: ProcessorDN, ComputerBrandDN, HardDiskDN and SolidStateDriveDN are all empty entities. The examples has to finish somewhere :). Also, MemoryModuleDN is an EmbeddedEntity.
Creative Commons License Signum Framework Site by Signum Software is licensed under a Creative Commons Attribution 3.0 License.
Powered by ScrewTurn Wiki version 3.0.5.600.