private static void Check_cascade_delete_flag_is_reflected_by_delete_behavior(
                bool isCascadeDelete, OperationAction expectedDeleteBehavior)
            {
                var tableDetails = new[]
                    {
                        CreateRow("catalog", "schema", "source", "Id", 0, false, "int", isIdentiy: true, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "target", "Id", 0, false, "int", isIdentiy: true)
                    };

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 0, isCascadeDelete, "catalog", "schema", "source", "Id", "catalog", "schema", "target",
                            "Id")
                    };

                var storeModelBuilder = CreateStoreModelBuilder();

                var entityRegister = new StoreModelBuilder.EntityRegister();
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSet = storeModelBuilder.TryCreateAssociationSet(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(1, associationTypes.Count);
                Assert.NotNull(associationSet);

                var associationType = associationTypes[0];

                Assert.False(MetadataItemHelper.IsInvalid(associationType));
                Assert.Null(associationType.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors"));

                var sourceEnd = associationType.AssociationEndMembers.FirstOrDefault();
                var targetEnd = associationType.AssociationEndMembers.ElementAtOrDefault(1);

                Assert.Equal(expectedDeleteBehavior, sourceEnd.DeleteBehavior);
                Assert.Equal(OperationAction.None, targetEnd.DeleteBehavior);
            }
            public static void TryCreateAssociationSet_does_not_create_set_if_association_is_missing_key_column()
            {
                var tableDetails = new[]
                    {
                        CreateRow("catalog", "schema", "source", "Id", 0, false, "int", isIdentiy: true, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "source", "Other", 1, false, "int", isIdentiy: false, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "target", "Id", 0, false, "int", isIdentiy: true)
                    };

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 0, false, "catalog", "schema", "source", "Id", "catalog", "schema", "target", "Id"),
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 1, false, "catalog", "schema", "source", "Other", "catalog", "schema", "target",
                            "Other")
                    };

                var storeModelBuilder = CreateStoreModelBuilder();

                var entityRegister = new StoreModelBuilder.EntityRegister();
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSet = storeModelBuilder.TryCreateAssociationSet(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(1, associationTypes.Count);
                Assert.Null(associationSet);

                var associationType = associationTypes[0];

                Assert.NotNull(associationType);
                Assert.Equal(2, associationType.AssociationEndMembers.Count);
                Assert.Null(associationType.Constraint);
                Assert.True(MetadataItemHelper.IsInvalid(associationType));

                var metaProperty = associationType.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors");

                Assert.NotNull(metaProperty);

                var errors = metaProperty.Value as List<EdmSchemaError>;

                Assert.NotNull(errors);
                Assert.Equal(1, errors.Count);

                var error = errors[0];

                Assert.Equal(EdmSchemaErrorSeverity.Warning, error.Severity);
                Assert.Equal((int)ModelBuilderErrorCode.AssociationMissingKeyColumn, error.ErrorCode);
            }
            private static void Check_two_column_relationship_expected_association_end_multiplicity(
                Version targetEntityFrameworkVersion,
                bool column1Nullable,
                bool column2Nullable,
                RelationshipMultiplicity expectedSourceEndMultiplicity,
                RelationshipMultiplicity expectedTargetEndMultiplicity)
            {
                var tableDetails = new[]
                    {
                        CreateRow(
                            "catalog", "schema", "source", "Id", 0, isNullable: false, dataType: "int", isIdentiy: true, isPrimaryKey: true)
                        ,
                        CreateRow(
                            "catalog", "schema", "source", "Other", 1, isNullable: false, dataType: "int", isIdentiy: false,
                            isPrimaryKey: true),
                        CreateRow(
                            "catalog", "schema", "target", "Id", 0, isNullable: column1Nullable, dataType: "int", isIdentiy: true,
                            isPrimaryKey: true),
                        CreateRow(
                            "catalog", "schema", "target", "Other", 1, isNullable: column2Nullable, dataType: "int", isIdentiy: false,
                            isPrimaryKey: true)
                    };

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 0, false, "catalog", "schema", "source", "Id", "catalog", "schema", "target", "Id"),
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 0, false, "catalog", "schema", "source", "Other", "catalog", "schema", "target",
                            "Other")
                    };

                var storeModelBuilder = CreateStoreModelBuilder("System.Data.SqlClient", "2008", targetEntityFrameworkVersion);

                var entityRegister = new StoreModelBuilder.EntityRegister();
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSet = storeModelBuilder.TryCreateAssociationSet(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(1, associationTypes.Count);
                Assert.NotNull(associationSet);

                var associationType = associationTypes[0];

                Assert.False(MetadataItemHelper.IsInvalid(associationType));
                Assert.Null(associationType.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors"));

                var sourceEnd = associationType.AssociationEndMembers.FirstOrDefault();
                var targetEnd = associationType.AssociationEndMembers.ElementAtOrDefault(1);

                Assert.Equal(expectedSourceEndMultiplicity, sourceEnd.RelationshipMultiplicity);
                Assert.Equal(expectedTargetEndMultiplicity, targetEnd.RelationshipMultiplicity);
            }
            public static void TryCreateAssociationSet_creates_valid_association_type_and_set()
            {
                var tableDetails = new[]
                    {
                        CreateRow("catalog", "schema", "source", "Id", 0, false, "int", isIdentiy: true, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "target", "Id", 0, false, "int", isIdentiy: true)
                    };

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 0, false, "catalog", "schema", "source", "Id", "catalog", "schema", "target", "Id")
                    };

                var storeModelBuilder = CreateStoreModelBuilder();

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entityTypes = entityRegister.EntityTypes;
                var entitySets = entityRegister.EntitySets;
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSet = storeModelBuilder.TryCreateAssociationSet(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(1, associationTypes.Count);
                Assert.NotNull(associationSet);

                var associationType = associationTypes[0];

                Assert.NotNull(associationType);
                Assert.Equal(2, associationType.AssociationEndMembers.Count);
                Assert.NotNull(associationType.Constraint);
                Assert.False(MetadataItemHelper.IsInvalid(associationType));
                Assert.Null(associationType.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors"));

                var sourceEnd = associationType.AssociationEndMembers.FirstOrDefault();
                var targetEnd = associationType.AssociationEndMembers.ElementAtOrDefault(1);

                Assert.Equal(entityTypes[0], sourceEnd.GetEntityType());
                Assert.Equal(entityTypes[1], targetEnd.GetEntityType());

                var sourceEndSet = associationSet.AssociationSetEnds.FirstOrDefault();
                var targetEndSet = associationSet.AssociationSetEnds.ElementAtOrDefault(1);

                Assert.Equal(entitySets[0], sourceEndSet.EntitySet);
                Assert.Equal(entitySets[1], targetEndSet.EntitySet);
            }
            private static void Check_does_not_create_set_if_end_entity_is_missing(bool sourceMissing, bool targetMissing)
            {
                var tableDetails = new[]
                    {
                        CreateRow("catalog", "schema", "source", "Id", 0, false, "int", isIdentiy: true, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "target", "Id", 0, false, "int", isIdentiy: true)
                    };

                var sourceColumn = sourceMissing ? "missing" : "source";
                var targetColumn = targetMissing ? "missing" : "target";

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId", "name", 0, false, "catalog", "schema", sourceColumn, "Id", "catalog", "schema", targetColumn,
                            "Id")
                    };

                var storeModelBuilder = CreateStoreModelBuilder();

                var entityRegister = new StoreModelBuilder.EntityRegister();
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSet = storeModelBuilder.TryCreateAssociationSet(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(1, associationTypes.Count);
                Assert.Null(associationSet);

                var associationType = associationTypes[0];

                Assert.NotNull(associationType);
                Assert.Equal(0, associationType.AssociationEndMembers.Count);
                Assert.Null(associationType.Constraint);
                Assert.True(MetadataItemHelper.IsInvalid(associationType));

                var metaProperty = associationType.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors");

                Assert.NotNull(metaProperty);

                var errors = metaProperty.Value as List<EdmSchemaError>;
                var expectedCount = (sourceMissing ? 1 : 0) + (targetMissing ? 1 : 0);

                Assert.NotNull(errors);
                Assert.Equal(expectedCount, errors.Count);

                foreach (var error in errors)
                {
                    Assert.Equal(EdmSchemaErrorSeverity.Error, error.Severity);
                    Assert.Equal((int)ModelBuilderErrorCode.MissingEntity, error.ErrorCode);
                }
            }
            public static void CreateAssociationSets_creates_expected_association_types_and_sets()
            {
                var tableDetails = new[]
                    {
                        CreateRow(
                            "catalog", "schema", "source1", "Id", 0, isNullable: false, dataType: "int", isIdentiy: true, isPrimaryKey: true)
                        ,
                        CreateRow(
                            "catalog", "schema", "source1", "Other", 1, isNullable: false, dataType: "int", isIdentiy: false,
                            isPrimaryKey: true),
                        CreateRow("catalog", "schema", "target1", "Id", 0, isNullable: false, dataType: "int", isIdentiy: true),
                        CreateRow("catalog", "schema", "target1", "Other", 1, isNullable: false, dataType: "int", isIdentiy: false),
                        CreateRow(
                            "catalog", "schema", "source2", "Id", 0, isNullable: false, dataType: "int", isIdentiy: true, isPrimaryKey: true)
                        ,
                        CreateRow("catalog", "schema", "target2", "Id", 0, isNullable: false, dataType: "int", isIdentiy: true)
                    };

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId1", "name1", 0, false, "catalog", "schema", "source1", "Id", "catalog", "schema", "target1", "Id"),
                        CreateRelationshipDetailsRow(
                            "RelationshipId1", "name1", 1, false, "catalog", "schema", "source1", "Other", "catalog", "schema", "target1",
                            "Other"),
                        CreateRelationshipDetailsRow(
                            "RelationshipId2", "name2", 0, false, "catalog", "schema", "source2", "Id", "catalog", "schema", "target2", "Id")
                    };

                var storeModelBuilder = CreateStoreModelBuilder();

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entityTypes = entityRegister.EntityTypes;
                var entitySets = entityRegister.EntitySets;
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSets = storeModelBuilder.CreateAssociationSets(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(2, associationTypes.Count);
                Assert.Equal(2, associationSets.Count);

                var associationType1 = associationTypes[0];
                var associationType2 = associationTypes[1];

                Assert.Equal("myModel.name1", associationType1.FullName);
                Assert.Equal("myModel.name2", associationType2.FullName);
                Assert.Null(associationType1.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors"));
                Assert.Null(associationType2.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors"));
                Assert.False(MetadataItemHelper.IsInvalid(associationType1));
                Assert.False(MetadataItemHelper.IsInvalid(associationType2));
            }
            public static void CreateAssociationSets_does_not_create_set_for_shared_foreign_key()
            {
                var tableDetails = new[]
                    {
                        CreateRow("catalog", "schema", "source1", "Id", 0, false, "int", isIdentiy: true, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "source2", "Id", 0, false, "int", isIdentiy: true, isPrimaryKey: true),
                        CreateRow("catalog", "schema", "target", "Id", 0, false, "int", isIdentiy: true)
                    };

                var relationshipDetails = new List<RelationshipDetailsRow>
                    {
                        CreateRelationshipDetailsRow(
                            "RelationshipId1", "name1", 0, false, "catalog", "schema", "source1", "Id", "catalog", "schema", "target", "Id"),
                        CreateRelationshipDetailsRow(
                            "RelationshipId2", "name2", 0, false, "catalog", "schema", "source2", "Id", "catalog", "schema", "target", "Id"),
                    };

                var storeModelBuilder = CreateStoreModelBuilder();

                var entityRegister = new StoreModelBuilder.EntityRegister();
                storeModelBuilder.CreateEntitySets(tableDetails, new TableDetailsRow[0], entityRegister);

                var associationTypes = new List<AssociationType>();
                var associationSets = storeModelBuilder.CreateAssociationSets(relationshipDetails, entityRegister, associationTypes);

                Assert.Equal(2, associationTypes.Count);
                Assert.Equal(1, associationSets.Count);

                var associationType1 = associationTypes[0];
                var associationType2 = associationTypes[1];

                Assert.False(MetadataItemHelper.IsInvalid(associationType1));
                Assert.True(MetadataItemHelper.IsInvalid(associationType2));

                Assert.Null(associationType1.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors"));

                var metaProperty = associationType2.MetadataProperties.SingleOrDefault(p => p.Name == "EdmSchemaErrors");

                Assert.NotNull(metaProperty);

                var errors = metaProperty.Value as List<EdmSchemaError>;

                Assert.NotNull(errors);
                Assert.Equal(1, errors.Count);

                var error = errors[0];

                Assert.Equal(EdmSchemaErrorSeverity.Warning, error.Severity);
                Assert.Equal((int)ModelBuilderErrorCode.SharedForeignKey, error.ErrorCode);
            }
            public static void CreateEntitySets_creates_EntitySets_with_defining_queries_for_tables_and_views()
            {
                var tableDetailsRowsForTables =
                    new[]
                        {
                            CreateRow("catalog", "dbo", "Customer", "Id", 0, true, "int", isPrimaryKey: false),
                            CreateRow("catalog", "dbo", "Customer", "SSN", 0, false, "nvarchar", isPrimaryKey: false),
                        };

                var tableDetailsRowsForViews =
                    new[]
                        {
                            CreateRow("catalog", "dbo", "EvenBetterCustomer", "Id", 0, true, "int", isPrimaryKey: false),
                            CreateRow("catalog", "dbo", "EvenBetterCustomer", "SSN", 0, false, "nvarchar", isPrimaryKey: false),
                        };

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entitySets = entityRegister.EntitySets;
                var entityTypes = entityRegister.EntityTypes;

                CreateStoreModelBuilder()
                    .CreateEntitySets(tableDetailsRowsForTables, tableDetailsRowsForViews, entityRegister);

                Assert.Equal(2, entitySets.Count);
                Assert.True(entitySets.All(s => s.DefiningQuery != null));
                Assert.Equal(2, entityTypes.Count);

                Assert.True(
                    entitySets[0].MetadataProperties.Any(
                        p => p.Name == StoreTypeMetadataPropertyName && (string)p.Value == "Tables"));

                Assert.True(
                    entitySets[1].MetadataProperties.Any(
                        p => p.Name == StoreTypeMetadataPropertyName && (string)p.Value == "Views"));
            }
            public static void CreateEntitySets_does_not_create_EntitySet_for_invalid_EntityType()
            {
                var inputTableDetailsRows =
                    new[]
                        {
                            CreateRow("catalog", null, "Customer", "Id", 0, /*isNullable*/ true, "int", isPrimaryKey: true),
                            CreateRow("catalog", null, "Customer", "location", 0, false, "geometry", isPrimaryKey: true)
                        };

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entitySets = entityRegister.EntitySets;
                var entityTypes = entityRegister.EntityTypes;
                var entitySetsForReadOnlyEntities = new List<EntitySet>();

                CreateStoreModelBuilder()
                    .CreateEntitySets(inputTableDetailsRows, entityRegister, entitySetsForReadOnlyEntities, DbObjectType.Table);

                Assert.Empty(entitySets);
                Assert.Equal(1, entityTypes.Count);
                Assert.Empty(entitySetsForReadOnlyEntities);
            }
            public static void CreateEntitySets_uses_table_when_entity_type_name_different_than_table_name()
            {
                const string tableName = "Customer.Details";
                const string entityTypeName = "Customer_Details";

                var inputTableDetailsRows =
                    new[]
                        {
                            CreateRow("catalog", "dbo", tableName, "Id", 0, false, "int", isPrimaryKey: true),
                        };

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entitySets = entityRegister.EntitySets;
                var entityTypes = entityRegister.EntityTypes;
                var entitySetsForReadOnlyEntities = new List<EntitySet>();

                CreateStoreModelBuilder()
                    .CreateEntitySets(inputTableDetailsRows, entityRegister, entitySetsForReadOnlyEntities, DbObjectType.Table);

                var entitySet = entitySets[0];
                Assert.Equal(entitySet.Table, tableName);
                Assert.Equal(entitySet.Name, entityTypeName);
            }
            public static void CreateEntitySets_creates_EntitySets_without_schema_if_schema_not_defined()
            {
                var inputTableDetailsRows =
                    new[]
                        {
                            CreateRow("catalog", null, "Customer", "Id", 0, false, "int", isPrimaryKey: true),
                        };

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entitySets = entityRegister.EntitySets;
                var entityTypes = entityRegister.EntityTypes;
                var entitySetsForReadOnlyEntities = new List<EntitySet>();

                CreateStoreModelBuilder()
                    .CreateEntitySets(inputTableDetailsRows, entityRegister, entitySetsForReadOnlyEntities, DbObjectType.Table);

                Assert.Equal(1, entitySets.Count);
                Assert.Null(entitySets[0].Schema);
                Assert.Empty(entitySetsForReadOnlyEntities);
            }
            public static void CreateEntitySets_creates_EntitySets_for_valid_non_readonly_view_entities()
            {
                var inputTableDetailsRows =
                    new[]
                        {
                            CreateRow("catalog", "dbo", "Customer", "Id", 0, false, "int", isPrimaryKey: true),
                            CreateRow("catalog", "dbo", "OrderLine", "Id", 0, false, "int", isPrimaryKey: true),
                            CreateRow("catalog", "dbo", "Customer", "Name", 1, false, "nvarchar", isPrimaryKey: false),
                        };

                var entityRegister = new StoreModelBuilder.EntityRegister();
                var entitySets = entityRegister.EntitySets;
                var entityTypes = entityRegister.EntityTypes;
                var entitySetsForReadOnlyEntities = new List<EntitySet>();

                CreateStoreModelBuilder()
                    .CreateEntitySets(inputTableDetailsRows, entityRegister, entitySetsForReadOnlyEntities, DbObjectType.View);

                Assert.Equal(2, entitySets.Count);
                Assert.Equal(2, entityTypes.Count);
                Assert.Empty(entitySetsForReadOnlyEntities);
                Assert.Equal(
                    entitySets.Select(s => s.ElementType.Name),
                    entityTypes.Select(t => t.Name));

                Assert.True(
                    entitySets
                        .All(
                            s =>
                            s.MetadataProperties.Any(
                                p => p.Name == StoreTypeMetadataPropertyName && (string)p.Value == "Views")));
            }