Skip to content

Instantly share code, notes, and snippets.

@angusbreno
Created April 1, 2021 19:43
Show Gist options
  • Save angusbreno/5401a1fef0a5d28827753215c62ed2e1 to your computer and use it in GitHub Desktop.
Save angusbreno/5401a1fef0a5d28827753215c62ed2e1 to your computer and use it in GitHub Desktop.
dbml generator
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace BiFrost.Web.DataManagement
{
public class EFDBMLService<TDbContext>
where TDbContext : DbContext
{
private readonly TDbContext context;
public EFDBMLService(TDbContext context)
{
this.context = context;
}
public string GenerateDBMLDocument()
{
var stringBuilder = new StringBuilder();
GenerateProject(stringBuilder);
GenerateTables(stringBuilder);
return stringBuilder.ToString();
}
private void GenerateProject(StringBuilder stringBuilder)
{
var rel = context.Model.Relational();
stringBuilder.AppendLine("Project " + rel.DefaultSchema + " {");
stringBuilder.AppendLine('\t' + "database_type: " + "'SQLServer'");
stringBuilder.AppendLine("}");
stringBuilder.AppendLine();
}
private void GenerateTables(StringBuilder stringBuilder)
{
var types = context.Model.GetEntityTypes().ToList();
foreach (var type in types)
{
if (type.IsOwned())
{
continue;
}
var rel = type.Relational();
stringBuilder.AppendLine("Table " + rel.TableName + " {");
var props = type.GetProperties().Where(x => !x.IsShadowProperty).ToList();
foreach (var prop in props)
{
GenerateProps(stringBuilder, prop);
}
var navs = type.GetNavigations().Where(x => !x.IsShadowProperty).ToList();
foreach (var nav in navs)
{
GenerateNavs(stringBuilder, nav);
}
stringBuilder.AppendLine("}");
stringBuilder.AppendLine();
}
}
private void GenerateNavs(StringBuilder stringBuilder, INavigation nav)
{
if (nav.IsCollection() || nav.IsDependentToPrincipal()) { return; }
var type = nav.DeclaringType.Model.FindEntityType(nav.ClrType);
if (type == null) { return; }
var props = type.GetProperties().Where(x => !x.IsShadowProperty).ToList();
foreach (var prop in props)
{
GenerateProps(stringBuilder, prop);
}
}
private void GenerateProps(StringBuilder stringBuilder, IProperty prop)
{
var rel = prop.Relational();
if (prop.ClrType.IsEnum)
{
stringBuilder.AppendLine('\t' + rel.ColumnName + " " + prop.ClrType.Name);
}
else
{
var foreings = prop.GetContainingForeignKeys();
var stringBuilder2 = new StringBuilder();
foreach (var foreing in foreings)
{
var rel2 = foreing.Relational();
var propsFk = foreing.PrincipalKey.Properties;
foreach (var propFk in propsFk)
{
var t = propsFk.FirstOrDefault().DeclaringEntityType.Relational().TableName;
var p = propsFk.FirstOrDefault().Relational().ColumnName;
stringBuilder2.Append(" [ref: > " + t + "." + p + "]");
}
}
stringBuilder.AppendLine('\t' + rel.ColumnName + " " + rel.ColumnType + stringBuilder2.ToString());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment