Cómo atravesar un dacpac
Estamos buscando actualizar nuestro dbproj a un sqlproj para que podamos apuntarlo a una nueva base de datos SQL 2012. Tenemos un programa en este momento que lee el archivo xml .dbschema para encontrar todas las tablas y columnas y recuperar información de ellas. Usamos estos datos para construir nuestras propias clases personalizadas.
El nuevo archivo sqlproj ahora produce un dacpac que queremos interrigir para obtener los datos que necesitamos. He escrito lo siguiente para intentar atravesar el dacpac y obtener la información que necesito:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SqlServer.Dac;
using Microsoft.SqlServer.Dac.Extensions;
using Microsoft.SqlServer.Dac.Model;
namespace DacPacReader
{
class Program
{
static void Main(string[] args)
{
using (System.IO.TextWriter writter = new System.IO.StreamWriter(@"c:\temp\output.txt"))
{
using (TSqlModel model = new TSqlModel(@"C:\temp\Data.dacpac"))
{
var allTables = model.GetObjects(DacQueryScopes.All, ModelSchema.Table);
foreach (var table in allTables)
{
writter.WriteLine(table.Name);
foreach (var column in table.GetChildren().Where(child => child.ObjectType.Name == "Column"))
{
writter.WriteLine("\t" + column.Name);
writter.WriteLine("\tProperties:");
foreach (var property in column.ObjectType.Properties)
{
writter.WriteLine("\t\t" + property.Name + "\t\t" + property.DataType.FullName);
}
writter.WriteLine("\tMetadata:");
foreach (var metaData in column.ObjectType.Metadata)
{
writter.WriteLine("\t\t" + metaData.Name + "\t\t" + metaData.DataType.FullName);
}
}
}
}
}
}
}
}
No tengo idea de si estoy haciendo esto de la manera correcta, o si hay una manera mucho mejor / más fácil. No estoy seguro de qué buscar en Google / S.E. y no puedo encontrar ningún ejemplo.
Puedo ver que la columna variable tiene un miembro no público llamado ContextObject que es un Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlSimpleColumn. Si pudiera acceder a este objeto, podría extraer toda la información que necesitaba. La tabla también tiene un ContextObject similar que me ayudaría.
De todos modos, actualmente esto abre el dacpac y recupera todos los nombres de tablas y columnas. Un ejemplo de los datos que obtengo es:
[dbo].[User]
[dbo].[User].[UserID]
Properties:
Collation System.String
IsIdentityNotForReplication System.Boolean
Nullable System.Boolean
IsRowGuidCol System.Boolean
Sparse System.Boolean
Expression Microsoft.Data.Tools.Schema.Sql.SchemaModel.SqlScriptProperty
Persisted System.Boolean
PersistedNullable System.Nullable`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Scale System.Int32
Precision System.Int32
Length System.Int32
IsMax System.Boolean
XmlStyle Microsoft.SqlServer.Dac.Model.XmlStyle
IdentityIncrement System.String
IdentitySeed System.String
IsFileStream System.Boolean
IsIdentity System.Boolean
Metadata:
ColumnType Microsoft.SqlServer.Dac.Model.ColumnType
Básicamente, me gustaría hacer uno de los siguientes:
Acceda a ContextObject para obtener un objeto Microsoft.Data.Tools.Schema.Sql.SchemaModel. * OObtenga el valor de la propiedad y los metadatos de las propiedades de ObjectType OComience de cero con una forma más fácil de obtener esta información.Necesitamos obtener información, como el tipo de columna, si es que puede contener nulos, y la escala y precisión de una columna