![]() |
VOOZH | about |
dotnet add package TabuLynx.Model.Extractor --version 0.7.0
NuGet\Install-Package TabuLynx.Model.Extractor -Version 0.7.0
<PackageReference Include="TabuLynx.Model.Extractor" Version="0.7.0" />
<PackageVersion Include="TabuLynx.Model.Extractor" Version="0.7.0" />Directory.Packages.props
<PackageReference Include="TabuLynx.Model.Extractor" />Project file
paket add TabuLynx.Model.Extractor --version 0.7.0
#r "nuget: TabuLynx.Model.Extractor, 0.7.0"
#:package TabuLynx.Model.Extractor@0.7.0
#addin nuget:?package=TabuLynx.Model.Extractor&version=0.7.0Install as a Cake Addin
#tool nuget:?package=TabuLynx.Model.Extractor&version=0.7.0Install as a Cake Tool
A powerful .NET library for extracting metadata and model structures from Analysis Services Tabular Models, including Power BI datasets, SSAS, and Microsoft Fabric. Built on top of TabuLynx.Query.Executor for robust DMV (Dynamic Management Views) querying capabilities.
dotnet add package TabuLynx.Model.Extractor
This package requires and builds upon:
Important: TabuLynx.Model.Extractor depends on TabuLynx.Query.Executor to execute DMV queries against Analysis Services. You must configure a query executor before using the model extractor.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using TabuLynx.Core.Configuration;
using TabuLynx.Query.Executor;
using TabuLynx.Model.Extractor;
using TabuLynx.Model.Extractor.Interfaces;
var host = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
// Configure TabuLynx options
services.Configure<TabuLynxOptions>(context.Configuration.GetSection("TabuLynx"));
// Add query executor (required dependency)
services.AddAdomdQueryExecutorForLocalPowerBI();
// Add model extractor
services.AddDmvModelExtractor();
})
.Build();
var modelExtractor = host.Services.GetRequiredService<IModelExtractor>();
var model = await modelExtractor.ExtractModelAsync();
Console.WriteLine($"Extracted model with {model.Tables.Count} tables");
{
"TabuLynx": {
"ConnectionString": "Provider=MSOLAP;Data Source=localhost:{port};"
}
}
using TabuLynx.Core.Configuration;
using TabuLynx.Query.Executor;
using TabuLynx.Model.Extractor;
using TabuLynx.Model.Extractor.Interfaces;
var builder = WebApplication.CreateBuilder(args);
// Configure services
builder.Services.Configure<TabuLynxOptions>(
builder.Configuration.GetSection("TabuLynx"));
// Add query executor (choose based on your target platform)
builder.Services.AddAdomdQueryExecutorForLocalPowerBI();
// OR: builder.Services.AddAdomdQueryExecutorForSsasServer();
// OR: builder.Services.AddAdomdQueryExecutorForFabric();
// Add model extractor
builder.Services.AddDmvModelExtractor();
var app = builder.Build();
app.MapGet("/model", async (IModelExtractor extractor) =>
{
var model = await extractor.ExtractModelAsync();
return Results.Ok(model);
});
app.MapGet("/model/json", async (IModelExtractor extractor) =>
{
var model = await extractor.ExtractModelAsync();
return Results.Content(model.ToJson(), "application/json");
});
app.Run();
The extracted TabularModel contains:
var model = await modelExtractor.ExtractModelAsync();
foreach (var table in model.Tables)
{
Console.WriteLine($"Table: {table.Name}");
Console.WriteLine($" Description: {table.Description}");
Console.WriteLine($" Hidden: {table.IsHidden}");
Console.WriteLine($" Columns: {table.Columns.Count}");
foreach (var column in table.Columns)
{
Console.WriteLine($" - {column.Name} ({column.DataType})");
if (column.IsKey) Console.WriteLine(" [Key Column]");
if (!string.IsNullOrEmpty(column.Expression))
Console.WriteLine($" Expression: {column.Expression}");
}
}
foreach (var measure in model.Measures)
{
Console.WriteLine($"Measure: {measure.Name}");
Console.WriteLine($" Expression: {measure.Expression}");
Console.WriteLine($" Table: {measure.TableName}");
Console.WriteLine($" Hidden: {measure.IsHidden}");
}
foreach (var relationship in model.Relationships)
{
Console.WriteLine($"Relationship: {relationship.Name}");
Console.WriteLine($" From: {relationship.FromTable}.{relationship.FromColumn}");
Console.WriteLine($" To: {relationship.ToTable}.{relationship.ToColumn}");
Console.WriteLine($" Type: {relationship.CrossFilteringBehavior}");
}
var model = await modelExtractor.ExtractModelAsync();
// Export full model to JSON
var jsonModel = model.ToJson(indented: true);
await File.WriteAllTextAsync("model.json", jsonModel);
// Create LLM-optimized version
var llmModel = model.ToLlmTabularModel(new TabularModel.LlmTabularModelOptions
{
IncludeHiddenTables = false,
IncludeHiddenColumns = false,
IncludeHiddenMeasures = false
});
var llmJson = llmModel.ToJson();
await File.WriteAllTextAsync("llm-model.json", llmJson);
public class ModelAnalyzer
{
private readonly IModelExtractor _modelExtractor;
public ModelAnalyzer(IModelExtractor modelExtractor)
{
_modelExtractor = modelExtractor;
}
public async Task<ModelStats> AnalyzeModelAsync()
{
var model = await _modelExtractor.ExtractModelAsync();
return new ModelStats
{
TotalTables = model.Tables.Count,
VisibleTables = model.Tables.Count(t => !t.IsHidden),
TotalColumns = model.Tables.SelectMany(t => t.Columns).Count(),
CalculatedColumns = model.CalculatedColumns.Count,
TotalMeasures = model.Measures.Count,
VisibleMeasures = model.Measures.Count(m => !m.IsHidden),
Relationships = model.Relationships.Count,
Hierarchies = model.Hierarchies.Count
};
}
}
public class ModelStats
{
public int TotalTables { get; set; }
public int VisibleTables { get; set; }
public int TotalColumns { get; set; }
public int CalculatedColumns { get; set; }
public int TotalMeasures { get; set; }
public int VisibleMeasures { get; set; }
public int Relationships { get; set; }
public int Hierarchies { get; set; }
}
public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
var environment = configuration["Environment"];
services.Configure<TabuLynxOptions>(configuration.GetSection("TabuLynx"));
// Configure query executor based on environment
switch (environment?.ToLower())
{
case "development":
services.AddAdomdQueryExecutorForLocalPowerBI();
break;
case "staging":
services.AddAdomdQueryExecutorForSsasServer();
break;
case "production":
services.AddAdomdQueryExecutorForFabric();
break;
}
// Add model extractor (works with any query executor)
services.AddDmvModelExtractor();
}
The model extractor uses the following Analysis Services DMV queries to extract metadata:
$SYSTEM.TMSCHEMA_TABLES - Table definitions$SYSTEM.TMSCHEMA_COLUMNS - Column definitions$SYSTEM.TMSCHEMA_MEASURES - Measure definitions$SYSTEM.TMSCHEMA_RELATIONSHIPS - Relationship definitions$SYSTEM.TMSCHEMA_HIERARCHIES - Hierarchy definitions// Generate model documentation
var model = await modelExtractor.ExtractModelAsync();
var documentation = GenerateModelDocumentation(model);
// Extract metadata for data catalog
var model = await modelExtractor.ExtractModelAsync();
var catalogEntries = model.Tables.Select(t => new CatalogEntry
{
Name = t.Name,
Type = "Table",
Description = t.Description,
Columns = t.Columns.Select(c => c.Name).ToList()
});
// Create LLM-friendly model representation
var model = await modelExtractor.ExtractModelAsync();
var llmModel = model.ToLlmTabularModel();
var prompt = $"Analyze this data model: {llmModel.ToJson()}";
Missing Query Executor: Ensure you've registered a query executor service before adding the model extractor:
// Required: Add query executor first
services.AddAdomdQueryExecutorForLocalPowerBI();
// Then: Add model extractor
services.AddDmvModelExtractor();
DMV Access Denied: Verify that your connection has permissions to query system DMVs. This typically requires:
Empty Model Results: Ensure the target Analysis Services instance is running and accessible via the configured connection string.
Contributions, issues, and feature requests are welcome! Please feel free to check the issues page.
This project is licensed under the terms specified in the LICENSE file.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 2 NuGet packages that depend on TabuLynx.Model.Extractor:
| Package | Downloads |
|---|---|
|
TabuLynx.Model.Extractor.Dax
Package Description |
|
|
TabuLynx.Model.Extractor.Tom
Package Description |
This package is not used by any popular GitHub repositories.