Obtaining the database schema, tables, columns, and primary keys in a single SQL call
I am currently writing an EntityFramework reverse engineer code-first generator. It will generate POCO classes, DbContext and Code First mapping for an existing database.
There is one already in Entity Framework Power Tools Beta 2 However this one is going to do the job right, and include table filtering!
Watch this space...
There is one already in Entity Framework Power Tools Beta 2 However this one is going to do the job right, and include table filtering!
Watch this space...
SELECT [Extent1].[SchemaName], [Extent1].[Name] AS TableName, [Extent1].[TABLE_TYPE] AS TableType, [UnionAll1].[Ordinal], [UnionAll1].[Name] AS ColumnName, [UnionAll1].[IsNullable], [UnionAll1].[TypeName], ISNULL([UnionAll1].[MaxLength],0) AS MaxLength, ISNULL([UnionAll1].[Precision], 0) AS Precision, ISNULL([UnionAll1].[Default], '') AS [Default], ISNULL([UnionAll1].[DateTimePrecision], '') AS [DateTimePrecision], ISNULL([UnionAll1].[Scale], 0) AS Scale, [UnionAll1].[IsIdentity], [UnionAll1].[IsStoreGenerated], CASE WHEN ([Project5].[C2] IS NULL) THEN CAST(0 AS BIT) ELSE [Project5].[C2] END AS PrimaryKey FROM ( SELECT QUOTENAME(TABLE_SCHEMA) + QUOTENAME(TABLE_NAME) [Id], TABLE_SCHEMA [SchemaName], TABLE_NAME [Name], TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE IN ('BASE TABLE', 'VIEW') ) AS [Extent1] INNER JOIN ( SELECT [Extent2].[Id] AS [Id], [Extent2].[Name] AS [Name], [Extent2].[Ordinal] AS [Ordinal], [Extent2].[IsNullable] AS [IsNullable], [Extent2].[TypeName] AS [TypeName], [Extent2].[MaxLength] AS [MaxLength], [Extent2].[Precision] AS [Precision], [Extent2].[Default], [Extent2].[DateTimePrecision] AS [DateTimePrecision], [Extent2].[Scale] AS [Scale], [Extent2].[IsIdentity] AS [IsIdentity], [Extent2].[IsStoreGenerated] AS [IsStoreGenerated], 0 AS [C1], [Extent2].[ParentId] AS [ParentId] FROM ( SELECT QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id], QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId], c.COLUMN_NAME [Name], c.ORDINAL_POSITION [Ordinal], CAST(CASE c.IS_NULLABLE WHEN 'YES' THEN 1 WHEN 'NO' THEN 0 ELSE 0 END AS BIT) [IsNullable], CASE WHEN c.DATA_TYPE IN ('varchar', 'nvarchar', 'varbinary') AND c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + '(max)' ELSE c.DATA_TYPE END AS [TypeName], c.CHARACTER_MAXIMUM_LENGTH [MaxLength], CAST(c.NUMERIC_PRECISION AS INTEGER) [Precision], CAST(c.DATETIME_PRECISION AS INTEGER) [DateTimePrecision], CAST(c.NUMERIC_SCALE AS INTEGER) [Scale], c.COLLATION_CATALOG [CollationCatalog], c.COLLATION_SCHEMA [CollationSchema], c.COLLATION_NAME [CollationName], c.CHARACTER_SET_CATALOG [CharacterSetCatalog], c.CHARACTER_SET_SCHEMA [CharacterSetSchema], c.CHARACTER_SET_NAME [CharacterSetName], CAST(0 AS BIT) AS [IsMultiSet], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsIdentity') AS BIT) AS [IsIdentity], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsComputed') | CASE WHEN c.DATA_TYPE = 'timestamp' THEN 1 ELSE 0 END AS BIT) AS [IsStoreGenerated], c.COLUMN_DEFAULT AS [Default] FROM INFORMATION_SCHEMA.COLUMNS c INNER JOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_CATALOG = t.TABLE_CATALOG AND c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW') ) AS [Extent2] UNION ALL SELECT [Extent3].[Id] AS [Id], [Extent3].[Name] AS [Name], [Extent3].[Ordinal] AS [Ordinal], [Extent3].[IsNullable] AS [IsNullable], [Extent3].[TypeName] AS [TypeName], [Extent3].[MaxLength] AS [MaxLength], [Extent3].[Precision] AS [Precision], [Extent3].[Default], [Extent3].[DateTimePrecision] AS [DateTimePrecision], [Extent3].[Scale] AS [Scale], [Extent3].[IsIdentity] AS [IsIdentity], [Extent3].[IsStoreGenerated] AS [IsStoreGenerated], 6 AS [C1], [Extent3].[ParentId] AS [ParentId] FROM ( SELECT QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id], QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId], c.COLUMN_NAME [Name], c.ORDINAL_POSITION [Ordinal], CAST(CASE c.IS_NULLABLE WHEN 'YES' THEN 1 WHEN 'NO' THEN 0 ELSE 0 END AS BIT) [IsNullable], CASE WHEN c.DATA_TYPE IN ('varchar', 'nvarchar', 'varbinary') AND c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + '(max)' ELSE c.DATA_TYPE END AS [TypeName], c.CHARACTER_MAXIMUM_LENGTH [MaxLength], CAST(c.NUMERIC_PRECISION AS INTEGER) [Precision], CAST(c.DATETIME_PRECISION AS INTEGER) AS [DateTimePrecision], CAST(c.NUMERIC_SCALE AS INTEGER) [Scale], c.COLLATION_CATALOG [CollationCatalog], c.COLLATION_SCHEMA [CollationSchema], c.COLLATION_NAME [CollationName], c.CHARACTER_SET_CATALOG [CharacterSetCatalog], c.CHARACTER_SET_SCHEMA [CharacterSetSchema], c.CHARACTER_SET_NAME [CharacterSetName], CAST(0 AS BIT) AS [IsMultiSet], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsIdentity') AS BIT) AS [IsIdentity], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsComputed') | CASE WHEN c.DATA_TYPE = 'timestamp' THEN 1 ELSE 0 END AS BIT) AS [IsStoreGenerated], c.COLUMN_DEFAULT [Default] FROM INFORMATION_SCHEMA.COLUMNS c INNER JOIN INFORMATION_SCHEMA.VIEWS v ON c.TABLE_CATALOG = v.TABLE_CATALOG AND c.TABLE_SCHEMA = v.TABLE_SCHEMA AND c.TABLE_NAME = v.TABLE_NAME WHERE NOT ( v.TABLE_SCHEMA = 'dbo' AND v.TABLE_NAME IN ('syssegments', 'sysconstraints') AND SUBSTRING(CAST(SERVERPROPERTY('productversion') AS VARCHAR(20)), 1, 1) = 8 ) ) AS [Extent3] ) AS [UnionAll1] ON (0 = [UnionAll1].[C1]) AND ([Extent1].[Id] = [UnionAll1].[ParentId]) LEFT OUTER JOIN ( SELECT [UnionAll2].[Id] AS [C1], CAST(1 AS BIT) AS [C2] FROM ( SELECT QUOTENAME(tc.CONSTRAINT_SCHEMA) + QUOTENAME(tc.CONSTRAINT_NAME) [Id], QUOTENAME(tc.TABLE_SCHEMA) + QUOTENAME(tc.TABLE_NAME) [ParentId], tc.CONSTRAINT_NAME [Name], tc.CONSTRAINT_TYPE [ConstraintType], CAST(CASE tc.IS_DEFERRABLE WHEN 'NO' THEN 0 ELSE 1 END AS BIT) [IsDeferrable], CAST(CASE tc.INITIALLY_DEFERRED WHEN 'NO' THEN 0 ELSE 1 END AS BIT) [IsInitiallyDeferred] FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc WHERE tc.TABLE_NAME IS NOT NULL ) AS [Extent4] INNER JOIN ( SELECT 7 AS [C1], [Extent5].[ConstraintId] AS [ConstraintId], [Extent6].[Id] AS [Id] FROM ( SELECT QUOTENAME(CONSTRAINT_SCHEMA) + QUOTENAME(CONSTRAINT_NAME) [ConstraintId], QUOTENAME(TABLE_SCHEMA) + QUOTENAME(TABLE_NAME) + QUOTENAME(COLUMN_NAME) [ColumnId] FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE ) AS [Extent5] INNER JOIN ( SELECT QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id], QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId], c.COLUMN_NAME [Name], c.ORDINAL_POSITION [Ordinal], CAST(CASE c.IS_NULLABLE WHEN 'YES' THEN 1 WHEN 'NO' THEN 0 ELSE 0 END AS BIT) [IsNullable], CASE WHEN c.DATA_TYPE IN ('varchar', 'nvarchar', 'varbinary') AND c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + '(max)' ELSE c.DATA_TYPE END AS [TypeName], c.CHARACTER_MAXIMUM_LENGTH [MaxLength], CAST(c.NUMERIC_PRECISION AS INTEGER) [Precision], CAST(c.DATETIME_PRECISION AS INTEGER) [DateTimePrecision], CAST(c.NUMERIC_SCALE AS INTEGER) [Scale], c.COLLATION_CATALOG [CollationCatalog], c.COLLATION_SCHEMA [CollationSchema], c.COLLATION_NAME [CollationName], c.CHARACTER_SET_CATALOG [CharacterSetCatalog], c.CHARACTER_SET_SCHEMA [CharacterSetSchema], c.CHARACTER_SET_NAME [CharacterSetName], CAST(0 AS BIT) AS [IsMultiSet], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsIdentity') AS BIT) AS [IsIdentity], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsComputed') | CASE WHEN c.DATA_TYPE = 'timestamp' THEN 1 ELSE 0 END AS BIT) AS [IsStoreGenerated], c.COLUMN_DEFAULT AS [Default] FROM INFORMATION_SCHEMA.COLUMNS c INNER JOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_CATALOG = t.TABLE_CATALOG AND c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.TABLE_NAME = t.TABLE_NAME AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW') ) AS [Extent6] ON [Extent6].[Id] = [Extent5].[ColumnId] UNION ALL SELECT 11 AS [C1], [Extent7].[ConstraintId] AS [ConstraintId], [Extent8].[Id] AS [Id] FROM ( SELECT CAST( NULL AS NVARCHAR (1)) [ConstraintId], CAST( NULL AS NVARCHAR (MAX)) [ColumnId] WHERE 1= 2 ) AS [Extent7] INNER JOIN ( SELECT QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) + QUOTENAME(c.COLUMN_NAME) [Id], QUOTENAME(c.TABLE_SCHEMA) + QUOTENAME(c.TABLE_NAME) [ParentId], c.COLUMN_NAME [Name], c.ORDINAL_POSITION [Ordinal], CAST(CASE c.IS_NULLABLE WHEN 'YES' THEN 1 WHEN 'NO' THEN 0 ELSE 0 END AS BIT) [IsNullable], CASE WHEN c.DATA_TYPE IN ('varchar', 'nvarchar', 'varbinary') AND c.CHARACTER_MAXIMUM_LENGTH = -1 THEN c.DATA_TYPE + '(max)' ELSE c.DATA_TYPE END AS [TypeName], c.CHARACTER_MAXIMUM_LENGTH [MaxLength], CAST(c.NUMERIC_PRECISION AS INTEGER) [Precision], CAST(c.DATETIME_PRECISION AS INTEGER) AS [DateTimePrecision], CAST(c.NUMERIC_SCALE AS INTEGER) [Scale], c.COLLATION_CATALOG [CollationCatalog], c.COLLATION_SCHEMA [CollationSchema], c.COLLATION_NAME [CollationName], c.CHARACTER_SET_CATALOG [CharacterSetCatalog], c.CHARACTER_SET_SCHEMA [CharacterSetSchema], c.CHARACTER_SET_NAME [CharacterSetName], CAST(0 AS BIT) AS [IsMultiSet], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsIdentity') AS BIT) AS [IsIdentity], CAST(COLUMNPROPERTY(OBJECT_ID(QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)), c.COLUMN_NAME, 'IsComputed') | CASE WHEN c.DATA_TYPE = 'timestamp' THEN 1 ELSE 0 END AS BIT) AS [IsStoreGenerated], c.COLUMN_DEFAULT [Default] FROM INFORMATION_SCHEMA.COLUMNS c INNER JOIN INFORMATION_SCHEMA.VIEWS v ON c.TABLE_CATALOG = v.TABLE_CATALOG AND c.TABLE_SCHEMA = v.TABLE_SCHEMA AND c.TABLE_NAME = v.TABLE_NAME WHERE NOT ( v.TABLE_SCHEMA = 'dbo' AND v.TABLE_NAME IN ('syssegments', 'sysconstraints') AND SUBSTRING(CAST(SERVERPROPERTY('productversion') AS VARCHAR(20)), 1, 1) = 8 ) ) AS [Extent8] ON [Extent8].[Id] = [Extent7].[ColumnId] ) AS [UnionAll2] ON (7 = [UnionAll2].[C1]) AND ([Extent4].[Id] = [UnionAll2].[ConstraintId]) WHERE [Extent4].[ConstraintType] = N'PRIMARY KEY' ) AS [Project5] ON [UnionAll1].[Id] = [Project5].[C1] WHERE NOT ([Extent1].[Name] IN ('EdmMetadata', '__MigrationHistory'))Do not add the following as it slows down the query by 97%. Do the sorting within your code instead.
ORDER BY [Extent1].[CatalogName], [Extent1].[SchemaName], [Extent1].[Name], [UnionAll1].[Ordinal]Foreign Keys for all tables in database:
SELECT FK_Table = FK.TABLE_NAME, FK_Column = CU.COLUMN_NAME, PK_Table = PK.TABLE_NAME, PK_Column = PT.COLUMN_NAME, Constraint_Name = C.CONSTRAINT_NAME, FK.TABLE_SCHEMA AS fkSchema, PK.TABLE_SCHEMA AS pkSchema FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME INNER JOIN ( SELECT i1.TABLE_NAME, i2.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1 INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY' ) PT ON PT.TABLE_NAME = PK.TABLE_NAME ORDER BY FK.TABLE_NAME, CU.COLUMN_NAME