public void Configure_mapping_can_process_simple_TPH_mapping()
        {
            //Setup
            var model = TestModelBuilderHelpers.CreateSimpleInheritanceTwoEntities();
            var databaseMapping = new DatabaseMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest).Generate(model);

            var entityType1 = model.GetEntityType("E1");
            var entityType2 = model.GetEntityType("E2");

            // Action
            var modelConfiguration = new ModelConfiguration();
            var entity1Configuration = modelConfiguration.Entity(entityType1.GetClrType());
            var entity1MappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity1MappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1MappingConfiguration, "disc")
                        {
                            Value = "foo"
                        });
            entity1Configuration.AddMappingConfiguration(entity1MappingConfiguration);
            var entity1SubTypeMappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity1SubTypeMappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1SubTypeMappingConfiguration, "disc")
                        {
                            Value = "bar"
                        });
            entity1Configuration.AddSubTypeMappingConfiguration(entityType2.GetClrType(), entity1SubTypeMappingConfiguration);
            modelConfiguration.NormalizeConfigurations();
            modelConfiguration.Configure(databaseMapping, ProviderRegistry.Sql2008_ProviderManifest);

            //Validate
            var entitySetMapping = databaseMapping.GetEntitySetMapping(model.GetEntitySet(entityType1));
            Assert.NotNull(entitySetMapping);
            Assert.Equal(3, entitySetMapping.EntityTypeMappings.Count);
            var entityType1Mapping = databaseMapping.GetEntityTypeMapping(entityType1);
            var entityType1MappingConditions = databaseMapping.GetEntityTypeMappings(entityType1).Single(tm => !tm.IsHierarchyMapping);
            var entityType2Mapping = databaseMapping.GetEntityTypeMapping(entityType2);

            var table1 = entityType1Mapping.TypeMappingFragments.Single().Table;
            var table2 = entityType2Mapping.TypeMappingFragments.Single().Table;

            Assert.True(entityType1Mapping.IsHierarchyMapping);
            Assert.Equal(4, table1.Columns.Count);
            Assert.Equal("P1", table1.Columns[0].Name);
            Assert.Equal("P2", table1.Columns[1].Name);
            Assert.Equal("P3", table1.Columns[2].Name);
            Assert.Equal("disc", table1.Columns[3].Name);
            Assert.Equal(2, entityType1Mapping.TypeMappingFragments.Single().PropertyMappings.Count);
            Assert.Equal("P1", entityType1Mapping.TypeMappingFragments.Single().PropertyMappings[0].Column.Name);
            Assert.Equal("P2", entityType1Mapping.TypeMappingFragments.Single().PropertyMappings[1].Column.Name);
            Assert.Same(table1.Columns[3], entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions.Single().Column);
            Assert.Equal("foo", entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions.Single().Value);
            Assert.Equal("nvarchar", entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions.Single().Column.TypeName);
            Assert.Equal(
                DatabaseMappingGenerator.DiscriminatorLength,
                entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions.Single().Column.Facets.MaxLength);

            Assert.False(entityType2Mapping.IsHierarchyMapping);
            Assert.Same(table1, table2);
            Assert.Equal(2, entityType2Mapping.TypeMappingFragments.Single().PropertyMappings.Count);
            Assert.Same(table1.Columns[0], table2.Columns[0]);
            Assert.Same(table1.Columns[1], table2.Columns[1]);
            Assert.Equal("P1", entityType2Mapping.TypeMappingFragments.Single().PropertyMappings[0].Column.Name);
            Assert.Equal("P3", entityType2Mapping.TypeMappingFragments.Single().PropertyMappings[1].Column.Name);
            Assert.Same(table2.Columns[3], entityType2Mapping.TypeMappingFragments.Single().ColumnConditions.Single().Column);
            Assert.Equal("bar", entityType2Mapping.TypeMappingFragments.Single().ColumnConditions.Single().Value);
        }
        public void Configure_mapping_can_process_one_level_TPH_on_both_sides_of_tree()
        {
            //Setup
            var model = TestModelBuilderHelpers.CreateSingleLevelInheritanceWithThreeEntities();
            var databaseMapping = new DatabaseMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest).Generate(model);

            var entityType1 = model.GetEntityType("E1");
            var entityType2 = model.GetEntityType("E2");
            var entityType3 = model.GetEntityType("E3");

            // Action
            var modelConfiguration = new ModelConfiguration();
            var entity1Configuration = modelConfiguration.Entity(entityType1.GetClrType());
            var entity1MappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity1MappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1MappingConfiguration, "P3")
                        {
                            Value = null
                        });
            entity1MappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1MappingConfiguration, "P4")
                        {
                            Value = null
                        });
            entity1Configuration.AddMappingConfiguration(entity1MappingConfiguration);
            var entity1SubTypeMappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity1SubTypeMappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1SubTypeMappingConfiguration, "P3")
                        {
                            Value = null
                        });
            entity1SubTypeMappingConfiguration
                .AddNullabilityCondition(
                    new NotNullConditionConfiguration(
                        entity1SubTypeMappingConfiguration,
                        new PropertyPath(entityType3.GetDeclaredPrimitiveProperty("P4").GetClrPropertyInfo())));
            entity1Configuration.AddSubTypeMappingConfiguration(entityType3.GetClrType(), entity1SubTypeMappingConfiguration);
            var entity2Configuration = modelConfiguration.Entity(entityType2.GetClrType());
            var entity2MappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity2MappingConfiguration
                .AddNullabilityCondition(
                    new NotNullConditionConfiguration(
                        entity2MappingConfiguration, new PropertyPath(entityType2.GetDeclaredPrimitiveProperty("P3").GetClrPropertyInfo())));
            entity2MappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity2MappingConfiguration, "P4")
                        {
                            Value = null
                        });
            entity2Configuration.AddMappingConfiguration(entity2MappingConfiguration);
            modelConfiguration.NormalizeConfigurations();
            modelConfiguration.Configure(databaseMapping, ProviderRegistry.Sql2008_ProviderManifest);

            //Validate
            var entitySetMapping = databaseMapping.GetEntitySetMapping(model.GetEntitySet(entityType1));
            Assert.NotNull(entitySetMapping);
            Assert.Equal(4, entitySetMapping.EntityTypeMappings.Count);

            var entityType1Mapping = databaseMapping.GetEntityTypeMapping(entityType1);
            var entityType1MappingConditions = databaseMapping.GetEntityTypeMappings(entityType1).Single(x => !x.IsHierarchyMapping);
            var entityType2Mapping = databaseMapping.GetEntityTypeMapping(entityType2);
            var entityType3Mapping = databaseMapping.GetEntityTypeMapping(entityType3);

            var table1 = entityType1Mapping.TypeMappingFragments.Single().Table;
            var table2 = entityType2Mapping.TypeMappingFragments.Single().Table;
            var table3 = entityType3Mapping.TypeMappingFragments.Single().Table;

            Assert.True(entityType1Mapping.IsHierarchyMapping);
            Assert.Equal(4, table1.Columns.Count);
            Assert.Equal("P1", table1.Columns[0].Name);
            Assert.Equal("P2", table1.Columns[1].Name);
            Assert.Equal("P3", table1.Columns[2].Name);
            Assert.Equal("P4", table1.Columns[3].Name);
            Assert.Equal(2, entityType1Mapping.TypeMappingFragments.Single().PropertyMappings.Count);
            Assert.Equal("P1", entityType1Mapping.TypeMappingFragments.Single().PropertyMappings[0].Column.Name);
            Assert.Equal("P2", entityType1Mapping.TypeMappingFragments.Single().PropertyMappings[1].Column.Name);
            Assert.Same(table1.Columns[2], entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions[0].Column);
            Assert.True((bool)entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions[0].IsNull);
            Assert.Same(table1.Columns[3], entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions[1].Column);
            Assert.True((bool)entityType1MappingConditions.TypeMappingFragments.Single().ColumnConditions[1].IsNull);

            Assert.False(entityType2Mapping.IsHierarchyMapping);
            Assert.Same(table1, table2);
            Assert.Same(table1.Columns[0], table2.Columns[0]);
            Assert.Same(table1.Columns[1], table2.Columns[1]);
            Assert.Equal(2, entityType2Mapping.TypeMappingFragments.Single().PropertyMappings.Count);
            Assert.Equal("P1", entityType2Mapping.TypeMappingFragments.Single().PropertyMappings[0].Column.Name);
            Assert.Equal("P3", entityType2Mapping.TypeMappingFragments.Single().PropertyMappings[1].Column.Name);
            Assert.Same(table1.Columns[3], entityType2Mapping.TypeMappingFragments.Single().ColumnConditions[0].Column);
            Assert.True((bool)entityType2Mapping.TypeMappingFragments.Single().ColumnConditions[0].IsNull);
            Assert.Same(table1.Columns[2], entityType2Mapping.TypeMappingFragments.Single().ColumnConditions[1].Column);
            Assert.False((bool)entityType2Mapping.TypeMappingFragments.Single().ColumnConditions[1].IsNull);

            Assert.False(entityType3Mapping.IsHierarchyMapping);
            Assert.Same(table1, table3);
            Assert.Same(table1.Columns[0], table3.Columns[0]);
            Assert.Same(table1.Columns[1], table3.Columns[1]);
            Assert.Equal(2, entityType3Mapping.TypeMappingFragments.Single().PropertyMappings.Count);
            Assert.Equal("P1", entityType3Mapping.TypeMappingFragments.Single().PropertyMappings[0].Column.Name);
            Assert.Equal("P4", entityType3Mapping.TypeMappingFragments.Single().PropertyMappings[1].Column.Name);
            Assert.Same(table1.Columns[2], entityType3Mapping.TypeMappingFragments.Single().ColumnConditions[0].Column);
            Assert.True((bool)entityType3Mapping.TypeMappingFragments.Single().ColumnConditions[0].IsNull);
            Assert.Same(table1.Columns[3], entityType3Mapping.TypeMappingFragments.Single().ColumnConditions[1].Column);
            Assert.False((bool)entityType3Mapping.TypeMappingFragments.Single().ColumnConditions[1].IsNull);
        }
        public void Configure_mapping_can_process_two_levels_of_TPH()
        {
            //Setup
            var model = TestModelBuilderHelpers.CreateTwoLevelInheritanceWithThreeEntities();
            var databaseMapping = new DatabaseMappingGenerator(ProviderRegistry.Sql2008_ProviderInfo, ProviderRegistry.Sql2008_ProviderManifest).Generate(model);

            var entityType1 = model.GetEntityType("E1");
            var entityType2 = model.GetEntityType("E2");
            var entityType3 = model.GetEntityType("E3");

            // Action
            var modelConfiguration = new ModelConfiguration();
            var entity1Configuration = modelConfiguration.Entity(entityType1.GetClrType());
            var entity1MappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity1MappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1MappingConfiguration, "disc")
                        {
                            Value = 1
                        });
            entity1Configuration.AddMappingConfiguration(entity1MappingConfiguration);
            var entity1SubTypeMappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity1SubTypeMappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity1SubTypeMappingConfiguration, "disc")
                        {
                            Value = 3
                        });
            entity1SubTypeMappingConfiguration
                .AddNullabilityCondition(
                    new NotNullConditionConfiguration(
                        entity1SubTypeMappingConfiguration,
                        new PropertyPath(
                            entityType3.GetDeclaredPrimitiveProperties().SingleOrDefault(p => p.Name == "P4").GetClrPropertyInfo())));
            entity1Configuration.AddSubTypeMappingConfiguration(entityType3.GetClrType(), entity1SubTypeMappingConfiguration);
            var entity2Configuration = modelConfiguration.Entity(entityType2.GetClrType());
            var entity2MappingConfiguration =
                new EntityMappingConfiguration
                    {
                        TableName = new DatabaseName("E1")
                    };
            entity2MappingConfiguration
                .AddValueCondition(
                    new ValueConditionConfiguration(entity2MappingConfiguration, "disc")
                        {
                            Value = 2
                        });
            entity2Configuration.AddMappingConfiguration(entity2MappingConfiguration);
            modelConfiguration.NormalizeConfigurations();
            modelConfiguration.Configure(databaseMapping, ProviderRegistry.Sql2008_ProviderManifest);

            //Validate
            var entitySetMapping = databaseMapping.GetEntitySetMapping(model.GetEntitySet(entityType1));
            Assert.NotNull(entitySetMapping);
            Assert.Equal(4, entitySetMapping.EntityTypeMappings.Count());

            var entityType1Mapping = databaseMapping.GetEntityTypeMapping(entityType1);
            var entityType1MappingConditions = databaseMapping.GetEntityTypeMappings(entityType1).Single(x => !x.IsHierarchyMapping);
            var entityType2Mapping = databaseMapping.GetEntityTypeMapping(entityType2);
            var entityType3Mapping = databaseMapping.GetEntityTypeMapping(entityType3);

            var table1 = entityType1Mapping.MappingFragments.Single().Table;
            var table2 = entityType2Mapping.MappingFragments.Single().Table;
            var table3 = entityType3Mapping.MappingFragments.Single().Table;

            Assert.True(entityType1Mapping.IsHierarchyMapping);
            Assert.Equal(5, table1.Properties.Count);
            Assert.Equal("P1", table1.Properties[0].Name);
            Assert.Equal("P2", table1.Properties[1].Name);
            Assert.Equal("P3", table1.Properties[2].Name);
            Assert.Equal("P4", table1.Properties[3].Name);
            Assert.Equal("disc", table1.Properties[4].Name);
            Assert.Equal(2, entityType1Mapping.MappingFragments.Single().ColumnMappings.Count());
            Assert.Equal("P1", entityType1Mapping.MappingFragments.Single().ColumnMappings.ElementAt(0).ColumnProperty.Name);
            Assert.Equal("P2", entityType1Mapping.MappingFragments.Single().ColumnMappings.ElementAt(1).ColumnProperty.Name);
            Assert.Same(
                table1.Properties[4], entityType1MappingConditions.MappingFragments.Single().ColumnConditions.Single().Column);
            Assert.Equal(1, entityType1MappingConditions.MappingFragments.Single().ColumnConditions.Single().Value);

            Assert.False(entityType2Mapping.IsHierarchyMapping);
            Assert.Same(table1, table2);
            Assert.Same(table1.Properties[0], table2.Properties[0]);
            Assert.Same(table1.Properties[1], table2.Properties[1]);
            Assert.Equal(2, entityType2Mapping.MappingFragments.Single().ColumnMappings.Count());
            Assert.Equal("P1", entityType2Mapping.MappingFragments.Single().ColumnMappings.ElementAt(0).ColumnProperty.Name);
            Assert.Equal("P3", entityType2Mapping.MappingFragments.Single().ColumnMappings.ElementAt(1).ColumnProperty.Name);
            Assert.Same(table2.Properties[4], entityType2Mapping.MappingFragments.Single().ColumnConditions.Single().Column);
            Assert.Equal(2, entityType2Mapping.MappingFragments.Single().ColumnConditions.Single().Value);
            Assert.Null(entityType2Mapping.MappingFragments.Single().ColumnConditions.Single().IsNull);

            Assert.False(entityType3Mapping.IsHierarchyMapping);
            Assert.Same(table1, table3);
            Assert.Same(table1.Properties[0], table3.Properties[0]);
            Assert.Same(table1.Properties[1], table3.Properties[1]);
            Assert.Equal(3, entityType3Mapping.MappingFragments.Single().ColumnMappings.Count());
            Assert.Equal("P1", entityType3Mapping.MappingFragments.Single().ColumnMappings.ElementAt(0).ColumnProperty.Name);
            Assert.Equal("P3", entityType3Mapping.MappingFragments.Single().ColumnMappings.ElementAt(1).ColumnProperty.Name);
            Assert.Equal("P4", entityType3Mapping.MappingFragments.Single().ColumnMappings.ElementAt(2).ColumnProperty.Name);
            Assert.Same(table3.Properties[4], entityType3Mapping.MappingFragments.Single().ColumnConditions.ElementAt(0).Column);
            Assert.Equal(3, entityType3Mapping.MappingFragments.Single().ColumnConditions.ElementAt(0).Value);
            Assert.Equal("int", entityType3Mapping.MappingFragments.Single().ColumnConditions.ElementAt(0).Column.TypeName);
            Assert.Same(table3.Properties[3], entityType3Mapping.MappingFragments.Single().ColumnConditions.ElementAt(1).Column);
            Assert.Equal(false, entityType3Mapping.MappingFragments.Single().ColumnConditions.ElementAt(1).IsNull);
        }