Contents tagged with CTP5

  • Associations in EF Code First CTP5: Part 3 – One-to-One Foreign Key Associations

    This is the third post in a series that explains entity association mappings with EF Code First. I've described these association types so far: In the previous blog post we saw the limitations of shared primary key association and argued that this type of association is relatively rare and in many schemas, a one-to-one association is represented with a foreign key field and a unique constraint. Today we are going to discuss how this is done by learning about one-to-one foreign key associations.

    Introducing the Revised Model

    In this revised version, each User always have two addresses: one billing address and another one for delivery. The following figure shows the class diagram for this domain model:

    One-to-One Foreign Key Association

    Instead of sharing a primary key, two rows can have a foreign key relationship. One table has a foreign key column that references the primary key of the associated table (The source and target of this foreign key constraint can even be the same table: This is called a self-referencing relationship.). An additional constraint enforces this relationship as a real one to one. For example, by making the BillingAddressId column unique, we declare that a particular address can be referenced by at most one user, as a billing address. This isn’t as strong as the guarantee from a shared primary key association, which allows a particular address to be referenced by at most one user, period. With several foreign key columns (which is the case in our domain model since we also have a foreign key for DeliveryAddress), we can reference the same address target row several times. But in any case, two users can’t share the same address for the same purpose.

    The Object Model

    Let's start by creating an object model for our domain:
    public class User
    {
        public int UserId { getset; }
        public string FirstName { getset; }
        public string LastName { getset; }        
        public int BillingAddressId { getset; }
        public int DeliveryAddressId { getset; }
     
        public Address BillingAddress { getset; }
        public Address DeliveryAddress { getset; }
    }
     
    public class Address
    {
        public int AddressId { getset; }
        public string Street { getset; }
        public string City { getset; }
        public string PostalCode { getset; }   
    }
     
    public class EntityMappingContext : DbContext
    {
        public DbSet<User> Users { getset; }
        public DbSet<Address> Addresses { getset; }
    }
    As you can see, User class has introduced two new scalar properties as BillingAddressId and DeliveryAddressId as well as their related navigation properties (BillingAddress and DeliveryAddress).

    Configuring Foreign Keys With Fluent API

    BillingAddressId and DeliveryAddressId are foreign key scalar properties and representing the actual foreign key values that the relationships are established on. However, Code First will not recognize them as the foreign keys for the associations since their names are not aligned with the conventions that it has to infer foreign keys. Therefore, we need to use fluent API (or Data Annotations) to tell Code First about the foreign keys. Here is the fluent API code to identify the foreign key properties:
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .HasRequired(a => a.BillingAddress)
                    .WithMany()
                    .HasForeignKey(u => u.BillingAddressId);
     
        modelBuilder.Entity<User>()
                    .HasRequired(a => a.DeliveryAddress)
                    .WithMany()
                    .HasForeignKey(u => u.DeliveryAddressId);
    }
    Alternatively, we can use Data Annotations to achieve this. CTP5 introduced a new attribute in System.ComponentModel.DataAnnotations namespace which is called ForeignKeyAttribute and we can place it on a navigation property to specify the property that represents the foreign key of the relationship:
    public class User
    {
        public int UserId { getset; }
        public string FirstName { getset; }
        public string LastName { getset; }        
        public int BillingAddressId { getset; }
        public int DeliveryAddressId { getset; }       
        
        [ForeignKey("BillingAddressId")]
        public Address BillingAddress { getset; }
        
        [ForeignKey("DeliveryAddressId")]
        public Address DeliveryAddress { getset; }
    }
    However, we will not use this Data Annotation and will stick with our fluent API code for a reason that you'll see soon.

    Creating a SQL Server Schema

    The object model seems to be ready to give us the desired SQL schema, however, if we try to create a SQL Server database from it, we will get an InvalidOperationException with this message:
    "The database creation succeeded, but the creation of the database objects did not. See InnerException for details."
    The inner exception is a System.Data.SqlClient.SqlException containing this message:
    "Introducing FOREIGN KEY constraint 'User_DeliveryAddress' on table 'Users' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors."
    As you can tell from the type of the inner exception (SqlException), it has nothing to do with EF or Code First; it has been generated purely by SQL Server when Code First was trying to create a database based on our object model.

    SQL Server and Multiple Cascade Paths

    A Multiple cascade path happens when a cascade path goes from column col1 in table A to table B and also from column col2 in table A to table B. So it seems that Code First tried to turn on Cascade Delete for both BillingAddressId and DeliveryAddressId columns in Users table. In fact, Code First was trying to use Declarative Referential Integrity (DRI) to enforce cascade deletes and the problem is that SQL Server is not fully ANSI SQL-92 compliant when it comes to the cascading actions. In SQL Server, DRI forbids cascading updates or deletes in a multiple cascade path scenario.

    A KB article also explains why we received this error: "In SQL Server, a table cannot appear more than one time in a list of all the cascading referential actions that are started by either a DELETE or an UPDATE statement. For example, the tree of cascading referential actions must only have one path to a particular table on the cascading referential actions tree". (i.e. the User table appeared twice in a list of cascading referential actions started by a DELETE). Basically, SQL Server does simple counting of cascade paths and, rather than trying to work out whether any cycles actually exist, it assumes the worst and refuses to create the referential actions (Cascades).

    Therefore, depend on our database engine, we may or may not get this exception (For example, both Oracle and MySQL let us create Cascades in this scenario.).

    Overriding Code First Convention To Resolve the Problem

    As you saw, Code First automatically turns on Cascade Deletes on required one-to-many associations based on the conventions. However, in order to resolve the exception that we got from SQL Server, we have no choice other than overriding this convention and switching cascade deletes off on at least one of the associations and as of CTP5, the only way to accomplish this is by using fluent API. Let's switch it off on DeliveryAddress Association:
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .HasRequired(a => a.BillingAddress)
                    .WithMany()
                    .HasForeignKey(u => u.BillingAddressId);
     
        modelBuilder.Entity<User>()
                    .HasRequired(a => a.DeliveryAddress)
                    .WithMany()
                    .HasForeignKey(u => u.DeliveryAddressId).WillCascadeOnDelete(false);
    }

    One-to-One Foreign Key Associations in EF Code First

    As you may have noticed, both associations in the fluent API code has been configured as a many-to-one—not one-to-one, as you might have expected. The reason is simple: Code First (and EF in general) does not natively support one-to-one foreign key associations. In fact, EF does not support any association scenario that involves unique constraints at all. Fortunately, in this case we don’t care what’s on the target side of the association, so we can treat it like a to-one association without the many part. All we want is to express “This entity (User) has a property that is a reference to an instance of another entity (Address)” and use a foreign key field to represent that relationship. Basically EF still thinks that the relationship is many-to-one. This is a workaround for the current EF limitation which comes with two consequences: First, EF won't create any additional constraint for us to enforces this relationship as a one to one, we need to manually create it ourselves. The second limitation that this lack of support impose to us is more important: one to one foreign key associations cannot be bidirectional (i.e. we cannot define a User property on the Address class).

    Create a Unique Constraint To Enforce the Relationship as a Real One to One

    We can manually create unique constraints on the foreign keys in the database after Code First creates it for us but if you are like me and prefer to create your database in one shot then there is a way in CTP5 to have Code First create the constraints as part of its database creation process. For that we can take advantage of the new CTP5’s SqlCommand method on DbDatabase class which allows raw SQL commands to be executed against the database. The best place to invoke SqlCommand method for this purpose is inside a Seed method that has been overridden in a custom Initializer class:
    protected override void Seed(EntityMappingContext context)
    {
        context.Database.SqlCommand("ALTER TABLE Users ADD CONSTRAINT uc_Billing UNIQUE(BillingAddressId)");
        context.Database.SqlCommand("ALTER TABLE Users ADD CONSTRAINT uc_Delivery UNIQUE(DeliveryAddressId)");
    }
    This code adds unique constraints to the BillingAddressId and DeliveryAddressId columns in the DDL generated by Code First.

    SQL Schema

    The object model is ready now and Code First will create the following database schema for us:
    It is worth mentioning that we can still enforce cascade deletes for DeliveryAddress relationship. SQL Server allows enforcing Referential Integrity in two different ways. DRI that we just saw is the most basic yet least flexible way. The other way is to use Triggers. We can write a Delete Triggers on the primary table that either deletes the rows in the dependent table(s) or sets all corresponding foreign keys to NULL (In our case the foreign keys are Non-Nullable so it has to delete the dependent rows).

    Download

    Click here to download and run the one-to-one foreign key association sample that we have built in this blog post.

    Summary

    In this blog post we learned about one-to-one foreign key associations as a better way to represent one to one relationships. However, we saw some limitations such as the need for manual creation of unique constraints and also the fact that these type of associations cannot be bidirectional, all due to the lack of unique constraint support in EF. Support for unique constraints is going to require changes to the whole EF stack and it won't happen in the RTM targeted for this year as that RTM will be layered on top of the current .NET 4.0 functionality. That said, EF team has this feature on their list for the future, so hopefully it will be supported in a later release of EF and until then the workaround that I showed here is going to be the way to implement one-to-one foreign key associations in EF Code First.

    References

  • Inheritance with EF Code First: Part 3 – Table per Concrete Type (TPC)

    This is the third (and last) post in a series that explains different approaches to map an inheritance hierarchy with EF Code First. I've described these strategies in previous posts: In today’s blog post I am going to discuss Table per Concrete Type (TPC) which completes the inheritance mapping strategies supported by EF Code First. At the end of this post I will provide some guidelines to choose an inheritance strategy mainly based on what we've learned in this series.

    TPC and Entity Framework in the Past

    Table per Concrete type is somehow the simplest approach suggested, yet using TPC with EF is one of those concepts that has not been covered very well so far and I've seen in some resources that it was even discouraged. The reason for that is just because Entity Data Model Designer in VS2010 doesn't support TPC (even though the EF runtime does). That basically means if you are following EF's Database-First or Model-First approaches then configuring TPC requires manually writing XML in the EDMX file which is not considered to be a fun practice. Well, no more. You'll see that with Code First, creating TPC is perfectly possible with fluent API just like other strategies and you don't need to avoid TPC due to the lack of designer support as you would probably do in other EF approaches.

    Table per Concrete Type (TPC)

    In Table per Concrete type (aka Table per Concrete class) we use exactly one table for each (nonabstract) class. All properties of a class, including inherited properties, can be mapped to columns of this table, as shown in the following figure:
    As you can see, the SQL schema is not aware of the inheritance; effectively, we’ve mapped two unrelated tables to a more expressive class structure. If the base class was concrete, then an additional table would be needed to hold instances of that class. I have to emphasize that there is no relationship between the database tables, except for the fact that they share some similar columns.

    TPC Implementation in Code First

    Just like the TPT implementation, we need to specify a separate table for each of the subclasses. We also need to tell Code First that we want all of the inherited properties to be mapped as part of this table. In CTP5, there is a new helper method on EntityMappingConfiguration class called MapInheritedProperties that exactly does this for us. Here is the complete object model as well as the fluent API to create a TPC mapping:
    public abstract class BillingDetail
    {
        public int BillingDetailId { getset; }
        public string Owner { getset; }
        public string Number { getset; }
    }
            
    public class BankAccount : BillingDetail
    {
        public string BankName { getset; }
        public string Swift { getset; }
    }
            
    public class CreditCard : BillingDetail
    {
        public int CardType { getset; }
        public string ExpiryMonth { getset; }
        public string ExpiryYear { getset; }
    }
        
    public class InheritanceMappingContext : DbContext
    {
        public DbSet<BillingDetail> BillingDetails { getset; }
            
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<BankAccount>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("BankAccounts");
            });
     
            modelBuilder.Entity<CreditCard>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("CreditCards");
            });            
        }
    }
    The Importance of EntityMappingConfiguration Class
    As a side note, it worth mentioning that EntityMappingConfiguration class turns out to be a key type for inheritance mapping in Code First. Here is an snapshot of this class:
    namespace System.Data.Entity.ModelConfiguration.Configuration.Mapping
    {
        public class EntityMappingConfiguration<TEntityType> where TEntityType : class
        {
            public ValueConditionConfiguration Requires(string discriminator);
            public void ToTable(string tableName);
            public void MapInheritedProperties();
        }
    }
    As you have seen so far, we used its Requires method to customize TPH. We also used its ToTable method to create a TPT and now we are using its MapInheritedProperties along with ToTable method to create our TPC mapping.

    TPC Configuration is Not Done Yet!

    We are not quite done with our TPC configuration and there is more into this story even though the fluent API we saw perfectly created a TPC mapping for us in the database. To see why, let's start working with our object model. For example, the following code creates two new objects of BankAccount and CreditCard types and tries to add them to the database:
    using (var context = new InheritanceMappingContext())
    {
        BankAccount bankAccount = new BankAccount();
        CreditCard creditCard = new CreditCard() { CardType = 1 };
                    
        context.BillingDetails.Add(bankAccount);
        context.BillingDetails.Add(creditCard);
     
        context.SaveChanges();
    }
    Running this code throws an InvalidOperationException with this message:
    The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
    The reason we got this exception is because DbContext.SaveChanges() internally invokes SaveChanges method of its internal ObjectContext. ObjectContext's SaveChanges method on its turn by default calls AcceptAllChanges after it has performed the database modifications. AcceptAllChanges method merely iterates over all entries in ObjectStateManager and invokes AcceptChanges on each of them. Since the entities are in Added state, AcceptChanges method replaces their temporary EntityKey with a regular EntityKey based on the primary key values (i.e. BillingDetailId) that come back from the database and that's where the problem occurs since both the entities have been assigned the same value for their primary key by the database (i.e. on both BillingDetailId = 1) and the problem is that ObjectStateManager cannot track objects of the same type (i.e. BillingDetail) with the same EntityKey value hence it throws. If you take a closer look at the TPC's SQL schema above, you'll see why the database generated the same values for the primary keys: the BillingDetailId column in both BankAccounts and CreditCards table has been marked as identity.

    How to Solve The Identity Problem in TPC

    As you saw, using SQL Server’s int identity columns doesn't work very well together with TPC since there will be duplicate entity keys when inserting in subclasses tables with all having the same identity seed. Therefore, to solve this, either a spread seed (where each table has its own initial seed value) will be needed, or a mechanism other than SQL Server’s int identity should be used. Some other RDBMSes have other mechanisms allowing a sequence (identity) to be shared by multiple tables, and something similar can be achieved with GUID keys in SQL Server. While using GUID keys, or int identity keys with different starting seeds will solve the problem but yet another solution would be to completely switch off identity on the primary key property. As a result, we need to take the responsibility of providing unique keys when inserting records to the database. We will go with this solution since it works regardless of which database engine is used.

    Switching Off Identity in Code First

    We can switch off identity simply by placing DatabaseGenerated attribute on the primary key property and pass DatabaseGenerationOption.None to its constructor. DatabaseGenerated attribute is a new data annotation which has been added to System.ComponentModel.DataAnnotations namespace in CTP5:
    public abstract class BillingDetail
    {
        [DatabaseGenerated(DatabaseGenerationOption.None)]
        public int BillingDetailId { getset; }
        public string Owner { getset; }
        public string Number { getset; }
    }
    As always, we can achieve the same result by using fluent API, if you prefer that:
    modelBuilder.Entity<BillingDetail>()
                .Property(p => p.BillingDetailId)
                .HasDatabaseGenerationOption(DatabaseGenerationOption.None);

    Working With The Object Model

    Our TPC mapping is ready and we can try adding new records to the database. But, like I said, now we need to take care of providing unique keys when creating new objects:
    using (var context = new InheritanceMappingContext())
    {
        BankAccount bankAccount = new BankAccount() 
        { 
            BillingDetailId = 1                     
        };
        CreditCard creditCard = new CreditCard() 
        { 
            BillingDetailId = 2,
            CardType = 1
        };
                    
        context.BillingDetails.Add(bankAccount);
        context.BillingDetails.Add(creditCard);
     
        context.SaveChanges();
    }

    Polymorphic Associations with TPC is Problematic

    The main problem with this approach is that it doesn’t support Polymorphic Associations very well. After all, in the database, associations are represented as foreign key relationships and in TPC, the subclasses are all mapped to different tables so a polymorphic association to their base class (abstract BillingDetail in our example) cannot be represented as a simple foreign key relationship. For example, consider the domain model we introduced here where User has a polymorphic association with BillingDetail. This would be problematic in our TPC Schema, because if User has a many-to-one relationship with BillingDetail, the Users table would need a single foreign key column, which would have to refer both concrete subclass tables. This isn’t possible with regular foreign key constraints.

    Schema Evolution with TPC is Complex

    A further conceptual problem with this mapping strategy is that several different columns, of different tables, share exactly the same semantics. This makes schema evolution more complex. For example, a change to a base class property results in changes to multiple columns. It also makes it much more difficult to implement database integrity constraints that apply to all subclasses.

    Generated SQL

    Let's examine SQL output for polymorphic queries in TPC mapping. For example, consider this polymorphic query for all BillingDetails and the resulting SQL statements that being executed in the database:
    var query = from b in context.BillingDetails select b;
    Just like the SQL query generated by TPT mapping, the CASE statements that you see in the beginning of the query is merely to ensure columns that are irrelevant for a particular row have NULL values in the returning flattened table. (e.g. BankName for a row that represents a CreditCard type).

    TPC's SQL Queries are Union Based

    As you can see in the above screenshot, the first SELECT uses a FROM-clause subquery (which is selected with a red rectangle) to retrieve all instances of BillingDetails from all concrete class tables. The tables are combined with a UNION operator, and a literal (in this case, 0 and 1) is inserted into the intermediate result; (look at the lines highlighted in yellow.) EF reads this to instantiate the correct class given the data from a particular row. A union requires that the queries that are combined, project over the same columns; hence, EF has to pad and fill up nonexistent columns with NULL. This query will really perform well since here we can let the database optimizer find the best execution plan to combine rows from several tables. There is also no Joins involved so it has a better performance than the SQL queries generated by TPT where a Join is required between the base and subclasses tables.

    Choosing Strategy Guidelines

    Before we get into this discussion, I want to emphasize that there is no one single "best strategy fits all scenarios" exists. As you saw, each of the approaches have their own advantages and drawbacks. Here are some rules of thumb to identify the best strategy in a particular scenario:
    • If you don’t require polymorphic associations or queries, lean toward TPC—in other words, if you never or rarely query for BillingDetails and you have no class that has an association to BillingDetail base class. I recommend TPC (only) for the top level of your class hierarchy, where polymorphism isn’t usually required, and when modification of the base class in the future is unlikely.
    • If you do require polymorphic associations or queries, and subclasses declare relatively few properties (particularly if the main difference between subclasses is in their behavior), lean toward TPH. Your goal is to minimize the number of nullable columns and to convince yourself (and your DBA) that a denormalized schema won’t create problems in the long run.
    • If you do require polymorphic associations or queries, and subclasses declare many properties (subclasses differ mainly by the data they hold), lean toward TPT. Or, depending on the width and depth of your inheritance hierarchy and the possible cost of joins versus unions, use TPC.
    By default, choose TPH only for simple problems. For more complex cases (or when you’re overruled by a data modeler insisting on the importance of nullability constraints and normalization), you should consider the TPT strategy. But at that point, ask yourself whether it may not be better to remodel inheritance as delegation in the object model (delegation is a way of making composition as powerful for reuse as inheritance). Complex inheritance is often best avoided for all sorts of reasons unrelated to persistence or ORM. EF acts as a buffer between the domain and relational models, but that doesn’t mean you can ignore persistence concerns when designing your classes.

    Summary

    In this series, we focused on one of the main structural aspect of the object/relational paradigm mismatch which is inheritance and discussed how EF solve this problem as an ORM solution. We learned about the three well-known inheritance mapping strategies and their implementations in EF Code First. Hopefully it gives you a better insight about the mapping of inheritance hierarchies as well as choosing the best strategy for your particular scenario.

    Happy New Year and Happy Code-Firsting!

    References

  • Inheritance with EF Code First: Part 2 – Table per Type (TPT)

    In the previous blog post you saw that there are three different approaches to representing an inheritance hierarchy and I explained Table per Hierarchy (TPH) as the default mapping strategy in EF Code First. We argued that the disadvantages of TPH may be too serious for our design since it results in denormalized schemas that can become a major burden in the long run. In today’s blog post we are going to learn about Table per Type (TPT) as another inheritance mapping strategy and we'll see that TPT doesn’t expose us to this problem.

    Table per Type (TPT)

    Table per Type is about representing inheritance relationships as relational foreign key associations. Every class/subclass that declares persistent properties—including abstract classes—has its own table. The table for subclasses contains columns only for each noninherited property (each property declared by the subclass itself) along with a primary key that is also a foreign key of the base class table. This approach is shown in the following figure:
    For example, if an instance of the CreditCard subclass is made persistent, the values of properties declared by the BillingDetail base class are persisted to a new row of the BillingDetails table. Only the values of properties declared by the subclass (i.e. CreditCard) are persisted to a new row of the CreditCards table. The two rows are linked together by their shared primary key value. Later, the subclass instance may be retrieved from the database by joining the subclass table with the base class table.

    TPT Advantages

    The primary advantage of this strategy is that the SQL schema is normalized. In addition, schema evolution is straightforward (modifying the base class or adding a new subclass is just a matter of modify/add one table). Integrity constraint definition are also straightforward (note how CardType in CreditCards table is now a non-nullable column).

    Implement TPT in EF Code First

    We can create a TPT mapping simply by placing Table attribute on the subclasses to specify the mapped table name (Table attribute is a new data annotation and has been added to System.ComponentModel.DataAnnotations namespace in CTP5):
    public abstract class BillingDetail
    {
        public int BillingDetailId { getset; }
        public string Owner { getset; }
        public string Number { getset; }
    }
     
    [Table("BankAccounts")]
    public class BankAccount : BillingDetail
    {
        public string BankName { getset; }
        public string Swift { getset; }
    }
     
    [Table("CreditCards")]
    public class CreditCard : BillingDetail
    {
        public int CardType { getset; }
        public string ExpiryMonth { getset; }
        public string ExpiryYear { getset; }
    }
     
    public class InheritanceMappingContext : DbContext
    {
        public DbSet<BillingDetail> BillingDetails { getset; }
    }
    If you prefer fluent API, then you can create a TPT mapping by using ToTable() method:
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BankAccount>().ToTable("BankAccounts");
        modelBuilder.Entity<CreditCard>().ToTable("CreditCards");
    }

    Polymorphic Associations

    A polymorphic association is an association to a base class, hence to all classes in the hierarchy with dynamic resolution of the concrete class at runtime. For example, consider the BillingInfo property of User in the following domain model. It references one particular BillingDetail object, which at runtime can be any concrete instance of that class.
    In fact, because BillingDetail is abstract, the association must refer to an instance of one of its subclasses only—CreditCard or BankAccount—at runtime.

    Implement Polymorphic Associations with EF Code First

    We don’t have to do anything special to enable polymorphic associations in EF Code First; The user needs a unidirectional association to some BillingDetails, which can be CreditCard or BankAccount so we just create this association and it would be naturally polymorphic:
    public class User
    {
        public int UserId { getset; }
        public string FirstName { getset; }
        public string LastName { getset; }
        public int BillingDetailId { getset; }
     
        public virtual BillingDetail BillingInfo { getset; }
    }
    In other words, as you can see above, a polymorphic association is an association that may refer instances of a subclass of the class that was explicitly specified as the type of the navigation property (e.g. User.BillingInfo).

    The following code demonstrates the creation of an association to an instance of the CreditCard subclass:
    using (var context = new InheritanceMappingContext())
    {
        CreditCard creditCard = new CreditCard()
        {                    
            Number   = "987654321",
            CardType = 1
        };                
        User user = new User()
        {
            UserId      = 1,    
            BillingInfo = creditCard
        }; 
        context.Users.Add(user);
        context.SaveChanges();
    }
    Now, if we navigate the association in a second context, EF Code First automatically retrieves the CreditCard instance:
    using (var context = new InheritanceMappingContext())
    {
        User user = context.Users.Find(1);
        Debug.Assert(user.BillingInfo is CreditCard);
    }

    Polymorphic Associations with TPT

    Another important advantage of TPT is the ability to handle polymorphic associations. In the database a polymorphic association to a particular base class will be represented as a foreign key referencing the table of that particular base class. (e.g. Users table has a foreign key that references BillingDetails table.)

    Generated SQL For Queries 

    Let’s take an example of a simple non-polymorphic query that returns a list of all the BankAccounts:
    var query = from b in context.BillingDetails.OfType<BankAccount>() select b;
    Executing this query (by invoking ToList() method) results in the following SQL statements being sent to the database (on the bottom, you can also see the result of executing the generated query in SQL Server Management Studio):
    Now, let’s take an example of a very simple polymorphic query that requests all the BillingDetails which includes both BankAccount and CreditCard types:
    var query = from b in context.BillingDetails select b;
    This LINQ query seems even more simple than the previous one but the resulting SQL query is not as simple as you might expect:
    As you can see, EF Code First relies on an INNER JOIN to detect the existence (or absence) of rows in the subclass tables CreditCards and BankAccounts so it can determine the concrete subclass for a particular row of the BillingDetails table. Also the SQL CASE statements that you see in the beginning of the query is just to ensure columns that are irrelevant for a particular row have NULL values in the returning flattened table. (e.g. BankName for a row that represents a CreditCard type)

    TPT Considerations

    Even though this mapping strategy is deceptively simple, the experience shows that performance can be unacceptable for complex class hierarchies because queries always require a join across many tables. In addition, this mapping strategy is more difficult to implement by hand— even ad-hoc reporting is more complex. This is an important consideration if you plan to use handwritten SQL in your application (For ad hoc reporting, database views provide a way to offset the complexity of the TPT strategy. A view may be used to transform the table-per-type model into the much simpler table-per-hierarchy model.)

    Summary

    In this post we learned about Table per Type as the second inheritance mapping in our series. So far, the strategies we’ve discussed require extra consideration with regard to the SQL schema (e.g. in TPT, foreign keys are needed). This situation changes with the Table per Concrete Type (TPC) that we will discuss in the next post.

    References

  • Inheritance with EF Code First: Part 1 – Table per Hierarchy (TPH)

    A simple strategy for mapping classes to database tables might be “one table for every entity persistent class.” This approach sounds simple enough and, indeed, works well until we encounter inheritance. Inheritance is such a visible structural mismatch between the object-oriented and relational worlds because object-oriented systems model both “is a” and “has a” relationships. SQL-based models provide only "has a" relationships between entities; SQL database management systems don’t support type inheritance—and even when it’s available, it’s usually proprietary or incomplete.

    There are three different approaches to representing an inheritance hierarchy:
    • Table per Hierarchy (TPH): Enable polymorphism by denormalizing the SQL schema, and utilize a type discriminator column that holds type information.
    • Table per Type (TPT): Represent "is a" (inheritance) relationships as "has a" (foreign key) relationships.
    • Table per Concrete class (TPC): Discard polymorphism and inheritance relationships completely from the SQL schema.
    I will explain each of these strategies in a series of posts and this one is dedicated to TPH. In this series we'll deeply dig into each of these strategies and will learn about "why" to choose them as well as "how" to implement them. Hopefully it will give you a better idea about which strategy to choose in a particular scenario.

    Inheritance Mapping with Entity Framework Code First

    All of the inheritance mapping strategies that we discuss in this series will be implemented by EF Code First CTP5. The CTP5 build of the new EF Code First library has been released by ADO.NET team earlier this month. EF Code-First enables a pretty powerful code-centric development workflow for working with data. I’m a big fan of the EF Code First approach, and I’m pretty excited about a lot of productivity and power that it brings. When it comes to inheritance mapping, not only Code First fully supports all the strategies but also gives you ultimate flexibility to work with domain models that involves inheritance. The fluent API for inheritance mapping in CTP5 has been improved a lot and now it's more intuitive and concise in compare to CTP4.

    A Note For Those Who Follow Other Entity Framework Approaches

    If you are following EF's "Database First" or "Model First" approaches, I still recommend to read this series since although the implementation is Code First specific but the explanations around each of the strategies is perfectly applied to all approaches be it Code First or others.

    A Note For Those Who are New to Entity Framework and Code-First

    If you choose to learn EF you've chosen well. If you choose to learn EF with Code First you've done even better. To get started, you can find a great walkthrough by Scott Guthrie here and another one by ADO.NET team here. In this post, I assume you already setup your machine to do Code First development and also that you are familiar with Code First fundamentals and basic concepts. You might also want to check out my other posts on EF Code First like Complex Types and Shared Primary Key Associations.

    A Top Down Development Scenario

    These posts take a top-down approach; it assumes that you’re starting with a domain model and trying to derive a new SQL schema. Therefore, we start with an existing domain model, implement it in C# and then let Code First create the database schema for us. However, the mapping strategies described are just as relevant if you’re working bottom up, starting with existing database tables. I’ll show some tricks along the way that help you dealing with nonperfect table layouts.

    The Domain Model

    In our domain model, we have a BillingDetail base class which is abstract (note the italic font on the UML class diagram below). We do allow various billing types and represent them as subclasses of BillingDetail class. As for now, we support CreditCard and BankAccount:

    Implement the Object Model with Code First

    As always, we start with the POCO classes. Note that in our DbContext, I only define one DbSet for the base class which is BillingDetail. Code First will find the other classes in the hierarchy based on Reachability Convention.
    public abstract class BillingDetail 
    {
        public int BillingDetailId { getset; }
        public string Owner { getset; }        
        public string Number { getset; }
    }
     
    public class BankAccount : BillingDetail
    {
        public string BankName { getset; }
        public string Swift { getset; }
    }
     
    public class CreditCard : BillingDetail
    {
        public int CardType { getset; }                
        public string ExpiryMonth { getset; }
        public string ExpiryYear { getset; }
    }
     
    public class InheritanceMappingContext : DbContext
    {
        public DbSet<BillingDetail> BillingDetails { getset; }
    }
    This object model is all that is needed to enable inheritance with Code First. If you put this in your application you would be able to immediately start working with the database and do CRUD operations. Before going into details about how EF Code First maps this object model to the database, we need to learn about one of the core concepts of inheritance mapping: polymorphic and non-polymorphic queries.

    Polymorphic Queries

    LINQ to Entities and EntitySQL, as object-oriented query languages, both support polymorphic queries—that is, queries for instances of a class and all instances of its subclasses, respectively. For example, consider the following query:
    IQueryable<BillingDetail> linqQuery = from b in context.BillingDetails select b;
    List<BillingDetail> billingDetails = linqQuery.ToList();
    Or the same query in EntitySQL:
    string eSqlQuery = @"SELECT VAlUE b FROM BillingDetails AS b";
    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
    ObjectQuery<BillingDetail> objectQuery = objectContext.CreateQuery<BillingDetail>(eSqlQuery);
    List<BillingDetail> billingDetails = objectQuery.ToList();
    linqQuery and eSqlQuery are both polymorphic and return a list of objects of the type BillingDetail, which is an abstract class but the actual concrete objects in the list are of the subtypes of BillingDetail: CreditCard and BankAccount.

    Non-polymorphic Queries

    All LINQ to Entities and EntitySQL queries are polymorphic which return not only instances of the specific entity class to which it refers, but all subclasses of that class as well. On the other hand, Non-polymorphic queries are queries whose polymorphism is restricted and only returns instances of a particular subclass. In LINQ to Entities, this can be specified by using OfType<T>() Method. For example, the following query returns only instances of BankAccount:
    IQueryable<BankAccount> query = from b in context.BillingDetails.OfType<BankAccount>() 
                                    select b;
    EntitySQL has OFTYPE operator that does the same thing:
    string eSqlQuery = @"SELECT VAlUE b FROM OFTYPE(BillingDetails, Model.BankAccount) AS b";
    In fact, the above query with OFTYPE operator is a short form of the following query expression that uses TREAT and IS OF operators:
    string eSqlQuery = @"SELECT VAlUE TREAT(b as Model.BankAccount) 
                         FROM BillingDetails AS b 
                         WHERE b IS OF(Model.BankAccount)";
    (Note that in the above query, Model.BankAccount is the fully qualified name for BankAccount class. You need to change "Model" with your own namespace name.)

    Table per Hierarchy (TPH)

    An entire class hierarchy can be mapped to a single table. This table includes columns for all properties of all classes in the hierarchy. The concrete subclass represented by a particular row is identified by the value of a type discriminator column. You don’t have to do anything special in Code First to enable TPH. It's the default inheritance mapping strategy:
    This mapping strategy is a winner in terms of both performance and simplicity. It’s the best-performing way to represent polymorphism—both polymorphic and nonpolymorphic queries perform well—and it’s even easy to implement by hand. Ad-hoc reporting is possible without complex joins or unions. Schema evolution is straightforward.

    Discriminator Column

    As you can see in the DB schema above, Code First has to add a special column to distinguish between persistent classes: the discriminator. This isn’t a property of the persistent class in our object model; it’s used internally by EF Code First. By default, the column name is "Discriminator", and its type is string. The values defaults to the persistent class names —in this case, “BankAccount” or “CreditCard”. EF Code First automatically sets and retrieves the discriminator values.

    TPH Requires Properties in SubClasses to be Nullable in the Database

    TPH has one major problem: Columns for properties declared by subclasses will be nullable in the database. For example, Code First created an (INT, NULL) column to map CardType property in CreditCard class. However, in a typical mapping scenario, Code First always creates an (INT, NOT NULL) column in the database for an int property in persistent class. But in this case, since BankAccount instance won’t have a CardType property, the CardType field must be NULL for that row so Code First creates an (INT, NULL) instead. If your subclasses each define several non-nullable properties, the loss of NOT NULL constraints may be a serious problem from the point of view of data integrity.

    TPH Violates the Third Normal Form

    Another important issue is normalization. We’ve created functional dependencies between nonkey columns, violating the third normal form. Basically, the value of Discriminator column determines the corresponding values of the columns that belong to the subclasses (e.g. BankName) but Discriminator is not part of the primary key for the table. As always, denormalization for performance can be misleading, because it sacrifices long-term stability, maintainability, and the integrity of data for immediate gains that may be also achieved by proper optimization of the SQL execution plans (in other words, ask your DBA).

    Generated SQL Query

    Let's take a look at the SQL statements that EF Code First sends to the database when we write queries in LINQ to Entities or EntitySQL. For example, the polymorphic query for BillingDetails that you saw, generates the following SQL statement:
    SELECT 
    [Extent1].[Discriminator] AS [Discriminator], 
    [Extent1].[BillingDetailId] AS [BillingDetailId], 
    [Extent1].[Owner] AS [Owner], 
    [Extent1].[Number] AS [Number], 
    [Extent1].[BankName] AS [BankName], 
    [Extent1].[Swift] AS [Swift], 
    [Extent1].[CardType] AS [CardType], 
    [Extent1].[ExpiryMonth] AS [ExpiryMonth], 
    [Extent1].[ExpiryYear] AS [ExpiryYear]
    FROM [dbo].[BillingDetails] AS [Extent1]
    WHERE [Extent1].[Discriminator] IN ('BankAccount','CreditCard')
    Or the non-polymorphic query for the BankAccount subclass generates this SQL statement:
    SELECT 
    [Extent1].[BillingDetailId] AS [BillingDetailId], 
    [Extent1].[Owner] AS [Owner], 
    [Extent1].[Number] AS [Number], 
    [Extent1].[BankName] AS [BankName], 
    [Extent1].[Swift] AS [Swift]
    FROM [dbo].[BillingDetails] AS [Extent1]
    WHERE [Extent1].[Discriminator] = 'BankAccount'
    Note how Code First adds a restriction on the discriminator column and also how it only selects those columns that belong to BankAccount entity.

    Change Discriminator Column Data Type and Values With Fluent API 

    Sometimes, especially in legacy schemas, you need to override the conventions for the discriminator column so that Code First can work with the schema. The following fluent API code will change the discriminator column name to "BillingDetailType" and the values to "BA" and "CC" for BankAccount and CreditCard respectively:
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BillingDetail>()
                    .Map<BankAccount>(m => m.Requires("BillingDetailType").HasValue("BA"))
                    .Map<CreditCard>(m => m.Requires("BillingDetailType").HasValue("CC"));
    }
    Also, changing the data type of discriminator column is interesting. In the above code, we passed strings to HasValue method but this method has been defined to accepts a type of object:
    public void HasValue(object value);
    Therefore, if for example we pass a value of type int to it then Code First not only use our desired values (i.e. 1 & 2) in the discriminator column but also changes the column type to be (INT, NOT NULL):
    modelBuilder.Entity<BillingDetail>()
                .Map<BankAccount>(m => m.Requires("BillingDetailType").HasValue(1))
                .Map<CreditCard>(m => m.Requires("BillingDetailType").HasValue(2));

    Summary

    In this post we learned about Table per Hierarchy as the default mapping strategy in Code First. The disadvantages of the TPH strategy may be too serious for your design—after all, denormalized schemas can become a major burden in the long run. Your DBA may not like it at all. In the next post, we will learn about Table per Type (TPT) strategy that doesn’t expose you to this problem.

    References

  • Associations in EF Code First CTP5: Part 2 – Shared Primary Key Associations

    In the previous blog post I demonstrated how to map a special kind of one-to-one association—a composition with complex types as the first post in a series about entity association mapping with EF Code First. We argued that the relationships between User and Address are best represented with a complex type mapping and we saw that this is usually the simplest way to represent one-to-one relationships but comes with some limitations.

    In today’s blog post I’m going to discuss how we can address those limitations by changing our mapping strategy. This is particularly useful for scenarios that we want a dedicated table for Address, so that we can map both User and Address as entities. One benefit of this model is the possibility for shared references— another entity class (let’s say Shipment) can also have a reference to a particular Address instance. If a User has a reference to this instance, as her BillingAddress, the Address instance has to support shared references and needs its own identity. In this case, User and Address classes have a true one-to-one association.

    Introducing the Revised Model

    In this revised version, each User could have one BillingAddress (Billing Association). Also Shipment has to be delivered to an address so it always has one Delivery Address (Delivery Association). Here is the class diagram for this domain model (note the multiplicities on association lines):
    In this model we assumed that the billing address of the user is the same as her delivery address. Now let’s create the association mappings for this domain model. There are several choices, the first being a One-to-One Primary Key Association.

    Shared Primary Associations

    Also know as One-to-One Primary Key Associations, means two related tables share the same primary key values. The primary key of one table is also a foreign key of the other. Let’s see how we map the primary key associations with Code First.

    How to Implement a One-to-One Primary Key Association with Code First

    First, we start with the POCO classes. As you can see, we've defined BillingAddress as a navigation property on User class and another one on Shipment class named DeliveryAddress. Both associations are unidirectional since we didn't define related navigation properties on Address class as for User and Shipment.
    public class User
    {
        public int UserId { getset; }
        public string FirstName { getset; }
        public string LastName { getset; }
        public virtual Address BillingAddress { getset; }
    }
     
    public class Address
    {
        public int AddressId { getset; }
        public string Street { getset; }
        public string City { getset; }
        public string PostalCode { getset; }
    }
     
    public class Shipment
    {
        public int ShipmentId { getset; }
        public DateTime CreatedOn { getset; }
        public string State { getset; }
        public virtual Address DeliveryAddress { getset; }
    }
     
    public class EntityMappingContext : DbContext
    {
        public DbSet<User> Users { getset; }
        public DbSet<Address> Addresses { getset; }
        public DbSet<Shipment> Shipments { getset; }
    }

    How Code First Reads This Object Model: One-to-Many

    Code First reads the model and tries to figure out the multiplicity of the associations. Since the associations are unidirectional, Code First takes this as if one Address has many Users and Many Shipments and will create a one-to-many association for each of them. So, what we were hoping for —a one-to-one association, is not inline with the conventions.

    How to Change the Multiplicity to One-to-One by Using the Conventions

    One way to turn our associations to be one-to-one is by making them bidirectional. That is, adding a new navigation property to Address class of type User and another one of type Shipment. By doing that we basically signal Code First that we are looking to have one-to-one associations since for example User has an Address and also Address has a User. Based on the conventions, Code First will change the multiplicity to one-to-one and this will solve the problem.

    Should We Make This Association Bidirectional?

    As always, the decision is up to us and depends on whether we need to navigate through our objects in that direction in the application code. In this case, we’d probably conclude that the bidirectional association doesn’t make much sense. If we call anAddress.User, we are saying “give me the user who has this address”, not a very reasonable request. So this is not a good option. Instead we'll keep our object model as it is and will resort to fluent API.

    How to Change the Multiplicity to One-to-One with Fluent API

    The following code is all that is needed to make the associations to be one-to-one. Note how the multiplicities in the UML class diagram (e.g. 1 on User and 0..1 on address) has been translated to the flunet API code by using HasRequired and HasOptional methods:
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasOptional(u => u.BillingAddress)
                                   .WithRequired();
        
        modelBuilder.Entity<Shipment>().HasRequired(u => u.DeliveryAddress)
                                       .WithOptional();
    }
    Also it worth mentioning that in CTP5, when we are mapping a one-to-one association with fluent API, we don't need to specify the foreign key as we would do when mapping a one-to-many association with HasForeignKey method. Since EF only supports one-to-one primary key associations it will automatically create the relationship in the database based on the primary keys and we don't need to state the obvious as we did in CTP4.

    Database Schema

    The mapping result for our object model is as follows (note the Identity column):

    Referential Integrity

    In relational database design the referential integrity rule states that each non-null value of a foreign key must match the value of some primary key. But wait, how does it even applies here? All we have is just three primary keys referencing each other. Who is the primary key and who is the foreign key? The best way to find the answer of this question is to take a look at the properties of the relationships in the database that has been created by Code First:
    As you can see, Code First adds a foreign key constraint which links the primary key of the Addresses table to the primary key of the Users table and adds another foreign key constraint that links the primary key of the Shipments table to the primary key of the Addresses table. The foreign key constraint means that a user has to exist for a particular address but not the other way around. In other words, the database guarantees that an Addresses row’s primary key references a valid Users primary key and a Shipments row’s primary key references a valid Addresses primary key.

    How Code First Determines Principal and Dependent?

    Code First has rules to determine the principal and dependent ends of an association. For one-to-many relationships the many end is always the dependent, but it gets a little tricky in one-to-one associations. In one-to-one associations Code First decides based on our object model, and possible data annotations or fluent API that we may have. For example in our case, we wrote this fluent API code to configure User-Address association:
    modelBuilder.Entity<User>().HasOptional(u => u.BillingAddress).WithRequired();
    This reads as "User entity has an optional association with one Address object but this association is required for Address entity."
    For Code First this is good enough to make the decision: It marked User as the principal end and Address as the dependent end in the association. Since we have the same fluent API code for the second association between Address and Shipment, it marks Address as the principal end and Shipment as the dependent end in this association as well.

    The referential integrity that we saw, is the first result of this Code First's principal/dependent decision.

    Second Result of Code First's Principal/Dependent Decision: Database Identity

    If you take a closer look at the above DB schema, you'll notice that only UserId has a regular identifier generator (aka Identity or Sequence) and AddressId and ShipmentId does not. This is a very important consequence of the principal/dependent decision for one-to-one associations: the dependent primary key will become non-Identity by default. This make sense because they share their primary key values and only one of them can be auto generated and we need to take care of providing valid keys for the rest.

    What about Cascade Deletes?

    As we saw, each Address always belongs to one User and each Shipment always delivered to one single Address. We want to make sure that when we delete a User the possible dependent rows on Address and Shipment also get deleted in the database. In fact, this is one of the Referential Integrity Refactorings which called Introduce Cascading Delete. The primary reason we would apply "Introduce Cascading Delete" is to preserve the referential integrity of our data by ensuring that related rows are appropriately deleted when a parent row is deleted. By default, Code First does not enable cascade delete when it creates a relationship in the database. As always we can override this convention with fluent API:
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasOptional(u => u.BillingAddress)
                                   .WithRequired()
                                   .WillCascadeOnDelete();
        
        modelBuilder.Entity<Shipment>().HasRequired(u => u.DeliveryAddress)
                                       .WithOptional()
                                       .WillCascadeOnDelete();
    }

    What If Both Ends are Required?

    We saw that the only reason Code First could figure out principal and dependent in our 1:1 associations was because our fluent API code clearly specified one end as Required and the other as Optional. But what if both endpoints are the same in terms of being required in the association? For example what if in our domain model, User always has one Address and Address always has one User (required on both end)? The answer is that ultimately, this scenario need to be configured by fluent API and the interesting point is that fluent API is designed in a way that will force you to explicitly specify who is dependent and who is principal in such cases that this cannot be inferred by Code First.

    To illustrate the idea, let's see how we can configure mapping for this User-Address association (Required/Required) with fluent API:
    modelBuilder.Entity<User>().HasRequired(u => u.BillingAddress).WithRequiredDependent();
    
    So we invoke WithRequiredDependent() after HasRequired() method. To see the reason, we need to take a look at the RequiredNavigationPropertyConfiguration type which is returned by HasRequired():
    public class RequiredNavigationPropertyConfiguration<TEntityType, TTargetEntityType>
    {
        public DependentNavigationPropertyConfiguration<TEntityType, TTargetEntityType> WithMany();
        public CascadableNavigationPropertyConfiguration WithOptional();
        public CascadableNavigationPropertyConfiguration WithRequiredDependent();
        public CascadableNavigationPropertyConfiguration WithRequiredPrincipal();
    }
    As you can see, if you want to go another Required after HasRequired() method, you have to either call WithRequiredDependent() or WithRequiredPrincipal() since there is no WithRequired() method on this RequiredNavigationPropertyConfiguration class which is returned by HasRequired() method.
    Both WithRequired and WithOptional methods return a CascadableNavigationPropertyConfiguration type which has a WillCascadeOnDelete() method. Now if we run the code and check the database, we'll see that cascade delete on both relationships are switched on.

    Working with the Model

    Here is an example for adding a new user along with its billing address. EF is smart enough to use the newly generated UserId for the AddressId as well:
    using (var context = new EntityMappingContext())
    {
        Address billingAddress = new Address()
        {   
            Street = "Yonge St.",
            City   = "Toronto"                    
        };
        User morteza = new User()
        {                    
            FirstName      = "Morteza",
            LastName       = "Manavi",
            BillingAddress = billingAddress
        }; 
                
        context.Users.Add(morteza);                        
        context.SaveChanges();                
    }
    The following code is an example of adding a new Address and Shipment for an existing User (assuming that we have a User with UserId=2 in the database):
    using (var context = new EntityMappingContext())
    {
        Address deliveryAddress = new Address()
        {
            AddressId = 2,
            Street    = "Main St.",
            City      = "Seattle"
        };
        Shipment shipment = new Shipment()
        {
            ShipmentId      = 2,
            State           = "Shipped",
            CreatedOn       = DateTime.Now,
            DeliveryAddress = deliveryAddress
        };                
                   
        context.Shipments.Add(shipment);
        context.SaveChanges();      
    }

    Limitations of This Mapping

    There are two important limitations to associations mapped as shared primary key:
    • Difficulty in saving related objects: The main difficulty with this approach is ensuring that associated instances are assigned the same primary key value when the objects are saved. For example, when adding a new Address object, it's our responsibility to provide a unique AddressId that is also valid (a User can be found with such a value as UserId.)

    • Multiple addresses for User is not possible: With this mapping we cannot have more than one Address for User. At the beginning of this post, when we introduce our model, we assumed that the user has the same address for billing and delivery. But what if that's not the case? What if we also want to add a Home address to User for the deliveries? In the current setup, each row in the User table has a corresponding row in the Address table. Two addresses would require an additional address table, and this mapping style therefore wouldn’t be adequate.

    Summary

    In this post we learned about one-to-one associations which shared primary key is just one way to implement it. Shared primary key associations aren’t uncommon but are relatively rare. In many schemas, a one-to-one association is represented with a foreign key field and a unique constraint. In the next posts we will revisit the same domain model and will learn about other ways to map one-to-one associations that does not have the limitations of the shared primary key association mapping.

    References