Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional --internal-only parameter #2

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions DotnetEfDbcontextConverter/DotnetEfDbcontextConverter.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>LatestMajor</LangVersion>
</PropertyGroup>

</Project>
181 changes: 106 additions & 75 deletions DotnetEfDbcontextConverter/Program.cs
Original file line number Diff line number Diff line change
@@ -1,94 +1,125 @@
using System;
using System.IO;
using System.Linq;
using System.Text;

namespace DotnetEfDbcontextConverter
namespace DotnetEfDbcontextConverter;

internal class Program
{
class Program
private static void Main(string[] args)
{
static void Main(string[] args)
if (args.Length == 0)
{
if (args.Length == 0)
{
Console.WriteLine(
"Optimizes generated DbContext output of \"dotnet ef dbcontext scaffold\"." + Environment.NewLine +
" - Makes DB schema changeable at runtime" + Environment.NewLine +
" - Removes OnConfiguring method (including connectionString), so you can implement your own partial OnConfiguring method outside the generated context." + Environment.NewLine +
" - Optional parameter --winforms optimizes all generated .cs files in the context file's folder for usage in Windows Forms (grids etc)." + Environment.NewLine +
" - Optional parameter --no-schema does not include the static variable Schema" + Environment.NewLine +
Environment.NewLine +
"Usage: " + Environment.NewLine +
"DotnetEfDbcontextConverter.exe path\\myDbContext.cs [--winforms] [--no-schema]");

Console.ReadKey();

return;
}
Console.WriteLine(
"Optimizes generated DbContext output of \"dotnet ef dbcontext scaffold\"." + Environment.NewLine +
" - Makes DB schema changeable at runtime" + Environment.NewLine +
" - Removes OnConfiguring method (including connectionString), so you can implement your own partial OnConfiguring method outside the generated context." +
Environment.NewLine +
" - Optional parameter --winforms optimizes all generated .cs files in the context file's folder for usage in Windows Forms (grids etc)." +
Environment.NewLine +
" - Optional parameter --no-schema does not include the static variable Schema" + Environment.NewLine +
" - Optional parameter --internal-only makes all model files and the context internal. This is meant for projects with e.g. an sqlite datasource." +
Environment.NewLine +
Environment.NewLine +
"Usage: " + Environment.NewLine +
"DotnetEfDbcontextConverter.exe path\\myDbContext.cs [--winforms] [--no-schema] [--internal-only]");


string file = args[0];

String content = File.ReadAllText(file);
File.Copy(file, file + ".backup", true);

Console.WriteLine("Backup file generated.");

//Get original schema name
var addSchema = !args.Any(a => a == "--no-schema");
var lines = content.Split(Environment.NewLine).ToList();

if (addSchema) {
var schemaPosition = content.IndexOf("entity.ToTable(");
var origSchema = content.Substring(schemaPosition, 50);
try {
origSchema = origSchema.Split(",")[1].Trim().Trim('"');
var schemaEndPosition = origSchema.IndexOf('"');
origSchema = origSchema.Substring(0, schemaEndPosition);
} catch (IndexOutOfRangeException) //As an alternative method, use database name from connection string
{
schemaPosition = content.IndexOf("database=");
if (schemaPosition != -1) {
origSchema = content.Substring(schemaPosition);
origSchema = origSchema.Split(";", 2)[0].Trim().Replace("database=", "").Replace("\"", "").Replace(")", "");
} else // not found; connection string could possibly be anything except a RDBMS (e.g. SQLite-Datasource, ...)
origSchema = "";
}
Console.ReadKey();

//Insert static schema variable declaration
var staticVarDecl = Environment.NewLine + "\t\tpublic static string Schema = \"" + origSchema + "\";" + Environment.NewLine + Environment.NewLine;
if (!content.Contains(staticVarDecl) && origSchema != "") {
var staticVarPosition = content.IndexOf(": DbContext") + 20;
content = content.Insert(staticVarPosition, staticVarDecl);
}
return;
}

//Replace hard-coded schema name with variable
lines = lines.Select(line =>
line.Contains("entity.ToTable") && addSchema
? line.Replace($"\"{ origSchema }\"", "Schema")
: line
).ToList();

var file = args[0];

var content = File.ReadAllText(file);
File.Copy(file, file + ".backup", true);

Console.WriteLine("Backup file generated.");

//Get original schema name
var addSchema = args.All(a => a != "--no-schema");
var lines = content.Split(Environment.NewLine).ToList();

if (addSchema)
{
var schemaPosition = content.IndexOf("entity.ToTable(", StringComparison.Ordinal);
var origSchema = content.Substring(schemaPosition, 50);
try
{
origSchema = origSchema.Split(",")[1].Trim().Trim('"');
var schemaEndPosition = origSchema.IndexOf('"');
origSchema = origSchema[..schemaEndPosition];
}
//Remove OnConfiguring method
var onConfigStartpos = lines.FindIndex(o => o.Contains("protected override void OnConfiguring"));
lines.RemoveRange(onConfigStartpos, 8);

//For better WinForms / grid usage: Replace ICollection and HashSet with BindingList
//(E.g. using parent/child relations in grid, ICollection might have only 2 grid columns like "Count" or "ReadOnly"
//Alternative (untested): Use context.table.ToBindingList() as DataSource as described here: https://blogs.msdn.microsoft.com/efdesign/2010/09/08/data-binding-with-dbcontext/
if (args.Any(a => a == "--winforms"))
catch (IndexOutOfRangeException) //As an alternative method, use database name from connection string
{
var dir = new FileInfo(file).DirectoryName;
foreach (var f in Directory.GetFiles(dir, "*.cs"))
schemaPosition = content.IndexOf("database=", StringComparison.Ordinal);
if (schemaPosition != -1)
{
origSchema = content[schemaPosition..];
origSchema = origSchema.Split(";", 2)[0].Trim().Replace("database=", "").Replace("\"", "")
.Replace(")", "");
}
else // not found; connection string could possibly be anything except a RDBMS (e.g. SQLite-Datasource, ...)
{
var fcontent = File.ReadAllText(f);
fcontent = "using System.ComponentModel;" + Environment.NewLine + fcontent.Replace("ICollection<", "IList<").Replace("HashSet<", "BindingList<");
File.WriteAllText(f, fcontent, System.Text.Encoding.Default);
origSchema = "";
}
}

File.WriteAllLines(file, lines, System.Text.Encoding.Default);
//Insert static schema variable declaration
var staticVarDecl = Environment.NewLine + "\t\tpublic static string Schema = \"" + origSchema + "\";" +
Environment.NewLine + Environment.NewLine;
if (!content.Contains(staticVarDecl) && origSchema != "")
{
var staticVarPosition = content.IndexOf(": DbContext", StringComparison.Ordinal) + 20;
content = content.Insert(staticVarPosition, staticVarDecl);
}

//Replace hard-coded schema name with variable
lines = lines.Select(line =>
line.Contains("entity.ToTable") && addSchema
? line.Replace($"\"{origSchema}\"", "Schema")
: line
).ToList();
}

//Remove OnConfiguring method
var onConfigStartpos = lines.FindIndex(o => o.Contains("protected override void OnConfiguring"));
lines.RemoveRange(onConfigStartpos, 8);

Console.WriteLine("Converting finished.");
File.WriteAllLines(file, lines, Encoding.Default);

//For better WinForms / grid usage: Replace ICollection and HashSet with BindingList
//(E.g. using parent/child relations in grid, ICollection might have only 2 grid columns like "Count" or "ReadOnly"
//Alternative (untested): Use context.table.ToBindingList() as DataSource as described here: https://blogs.msdn.microsoft.com/efdesign/2010/09/08/data-binding-with-dbcontext/
if (args.Any(a => a == "--winforms"))
{
var dir = new FileInfo(file).DirectoryName;
foreach (var f in Directory.GetFiles(dir, "*.cs"))
{
var fcontent = File.ReadAllText(f);
fcontent = "using System.ComponentModel;" + Environment.NewLine +
fcontent.Replace("ICollection<", "IList<").Replace("HashSet<", "BindingList<");
File.WriteAllText(f, fcontent, Encoding.Default);
}
}

if (args.Any(a => a == "--internal-only"))
{
MakeClassesInternal(new FileInfo(file).DirectoryName);
}

Console.WriteLine("Converting finished.");
}

static void MakeClassesInternal(string directory)
{
foreach (var file in Directory.GetFiles(directory, "*.cs"))
{
var content = File.ReadAllText(file);
content = content.Replace("public partial class", "internal partial class");
File.WriteAllText(file, content, Encoding.Default);
}
}
}
}
Binary file modified coreapp-dll.zip
Binary file not shown.
Binary file modified coreapp-exe.zip
Binary file not shown.