diff --git a/EfEnumToLookup/EfEnumToLookup.csproj b/EfEnumToLookup/EfEnumToLookup.csproj
index 70a0b0e..32a5d14 100644
--- a/EfEnumToLookup/EfEnumToLookup.csproj
+++ b/EfEnumToLookup/EfEnumToLookup.csproj
@@ -47,13 +47,14 @@
+
-
+
diff --git a/EfEnumToLookup/LookupGenerator/ContextExtensions.cs b/EfEnumToLookup/LookupGenerator/ContextExtensions.cs
new file mode 100644
index 0000000..3ae32ad
--- /dev/null
+++ b/EfEnumToLookup/LookupGenerator/ContextExtensions.cs
@@ -0,0 +1,48 @@
+namespace EfEnumToLookup.LookupGenerator
+{
+ using System.Data.Entity;
+ using System.Data.Entity.Core.Metadata.Edm;
+ using System.Data.Entity.Core.Objects;
+ using System.Data.Entity.Infrastructure;
+ using System.Linq;
+ using System.Text.RegularExpressions;
+
+ public static class ContextExtensions
+ {
+ public static string GetTableName(this DbContext context) where T : class
+ {
+ var objectContext = ((IObjectContextAdapter)context).ObjectContext;
+
+ return objectContext.GetTableName();
+ }
+
+ public static string GetTableName(this ObjectContext context) where T : class
+ {
+ string sql = context.CreateObjectSet().ToTraceString();
+ Regex regex = new Regex("FROM (?.*) AS");
+ Match match = regex.Match(sql);
+
+ string table = match.Groups["table"].Value;
+ return table;
+ }
+
+ public static string GetDefaultSchema(this DbContext context)
+ {
+ ////var table = (((IObjectContextAdapter)context).ObjectContext).MetadataWorkspace.GetItems(DataSpace.SSpace).FirstOrDefault();
+
+ var table = (((IObjectContextAdapter)context).ObjectContext).MetadataWorkspace.GetItemCollection(DataSpace.SSpace)
+ .GetItems()
+ .Single()
+ .BaseEntitySets
+ .OfType()
+ .SingleOrDefault(s => !s.MetadataProperties.Contains("Type") || s.MetadataProperties["Type"].ToString() == "Tables");
+
+ if(table == null)
+ {
+ return "dbo";
+ }
+
+ return table.MetadataProperties["Schema"].Value.ToString();
+ }
+ }
+}
diff --git a/EfEnumToLookup/LookupGenerator/EnumParser.cs b/EfEnumToLookup/LookupGenerator/EnumParser.cs
index 3bd9351..9ecbe48 100644
--- a/EfEnumToLookup/LookupGenerator/EnumParser.cs
+++ b/EfEnumToLookup/LookupGenerator/EnumParser.cs
@@ -57,7 +57,8 @@ public IEnumerable GetLookupValues(Type lookup)
{
Id = (int)numericValue,
Name = EnumName(value),
- });
+ Description = EnumDescriptionValue(value)
+ });
}
return values;
}
@@ -70,12 +71,6 @@ public IEnumerable GetLookupValues(Type lookup)
///
private string EnumName(Enum value)
{
- var description = EnumDescriptionValue(value);
- if (description != null)
- {
- return description;
- }
-
var name = value.ToString();
if (SplitWords)
diff --git a/EfEnumToLookup/LookupGenerator/EnumToLookup.cs b/EfEnumToLookup/LookupGenerator/EnumToLookup.cs
index f8138ef..6578ab5 100644
--- a/EfEnumToLookup/LookupGenerator/EnumToLookup.cs
+++ b/EfEnumToLookup/LookupGenerator/EnumToLookup.cs
@@ -1,29 +1,28 @@
namespace EfEnumToLookup.LookupGenerator
{
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data.Entity;
- using System.Data.Entity.Infrastructure;
- using System.Data.SqlClient;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
-
- ///
- /// Makes up for a missing feature in Entity Framework 6.1
- /// Creates lookup tables and foreign key constraints based on the enums
- /// used in your model.
- /// Use the properties exposed to control behaviour.
- /// Run Apply from your Seed method in either your database initializer
- /// or your EF Migrations.
- /// It is safe to run repeatedly, and will ensure enum values are kept in line
- /// with your current code.
- /// Source code: https://github.com/timabell/ef-enum-to-lookup
- /// License: MIT
- ///
- public class EnumToLookup : IEnumToLookup
+ using System;
+ using System.Collections.Generic;
+ using System.Data.Entity;
+ using System.Data.Entity.Core.Metadata.Edm;
+ using System.Data.Entity.Infrastructure;
+ using System.Data.SqlClient;
+ using System.Linq;
+ using System.Reflection;
+ using System.Text;
+
+ ///
+ /// Makes up for a missing feature in Entity Framework 6.1
+ /// Creates lookup tables and foreign key constraints based on the enums
+ /// used in your model.
+ /// Use the properties exposed to control behaviour.
+ /// Run Apply from your Seed method in either your database initializer
+ /// or your EF Migrations.
+ /// It is safe to run repeatedly, and will ensure enum values are kept in line
+ /// with your current code.
+ /// Source code: https://github.com/timabell/ef-enum-to-lookup
+ /// License: MIT
+ ///
+ public class EnumToLookup : IEnumToLookup
{
private readonly EnumParser _enumParser;
@@ -31,7 +30,8 @@ public EnumToLookup()
{
// set default behaviour, can be overridden by setting properties on object before calling Apply()
NameFieldLength = 255;
- TableNamePrefix = "Enum_";
+ DescriptionFieldLength = 255;
+ TableNamePrefix = "Enum_";
_enumParser = new EnumParser { SplitWords = true };
}
@@ -51,12 +51,18 @@ public bool SplitWords
///
public int NameFieldLength { get; set; }
- ///
- /// Prefix to add to all the generated tables to separate help group them together
- /// and make them stand out as different from other tables.
- /// Defaults to "Enum_" set to null or "" to not have any prefix.
+ ///
+ /// The size of the Description field that will be added to the generated lookup tables.
+ /// Adjust to suit your data if required, defaults to 255.
///
- public string TableNamePrefix { get; set; }
+ public int DescriptionFieldLength { get; set; }
+
+ ///
+ /// Prefix to add to all the generated tables to separate help group them together
+ /// and make them stand out as different from other tables.
+ /// Defaults to "Enum_" set to null or "" to not have any prefix.
+ ///
+ public string TableNamePrefix { get; set; }
///
/// Suffix to add to all the generated tables to separate help group them together
@@ -110,7 +116,8 @@ private IDbHandler GetDbHandler()
IDbHandler dbHandler = new SqlServerHandler
{
NameFieldLength = NameFieldLength,
- TableNamePrefix = TableNamePrefix,
+ DescriptionFieldLength = DescriptionFieldLength,
+ TableNamePrefix = TableNamePrefix,
TableNameSuffix = TableNameSuffix,
};
return dbHandler;
@@ -136,16 +143,17 @@ from enm in enums
NumericType = enm.GetEnumUnderlyingType(),
Values = _enumParser.GetLookupValues(enm),
}).ToList();
-
+
var model = new LookupDbModel
{
Lookups = lookups,
References = enumReferences,
- };
+ Schema = context.GetDefaultSchema()
+ };
return model;
}
-
- private static int ExecuteSqlCommand(DbContext context, string sql, IEnumerable parameters = null)
+
+ private static int ExecuteSqlCommand(DbContext context, string sql, IEnumerable parameters = null)
{
if (parameters == null)
{
diff --git a/EfEnumToLookup/LookupGenerator/IDbHandler.cs b/EfEnumToLookup/LookupGenerator/IDbHandler.cs
index c26c47c..2f4ca31 100644
--- a/EfEnumToLookup/LookupGenerator/IDbHandler.cs
+++ b/EfEnumToLookup/LookupGenerator/IDbHandler.cs
@@ -12,11 +12,17 @@ internal interface IDbHandler
///
int NameFieldLength { get; set; }
- ///
- /// Prefix to add to all the generated tables to separate help group them together
- /// and make them stand out as different from other tables.
+ ///
+ /// The size of the Description field that will be added to the generated lookup tables.
+ /// Adjust to suit your data if required.
///
- string TableNamePrefix { get; set; }
+ int DescriptionFieldLength { get; set; }
+
+ ///
+ /// Prefix to add to all the generated tables to separate help group them together
+ /// and make them stand out as different from other tables.
+ ///
+ string TableNamePrefix { get; set; }
///
/// Suffix to add to all the generated tables to separate help group them together
diff --git a/EfEnumToLookup/LookupGenerator/LookupDbModel.cs b/EfEnumToLookup/LookupGenerator/LookupDbModel.cs
index e8d79b8..eab367b 100644
--- a/EfEnumToLookup/LookupGenerator/LookupDbModel.cs
+++ b/EfEnumToLookup/LookupGenerator/LookupDbModel.cs
@@ -9,6 +9,7 @@ namespace EfEnumToLookup.LookupGenerator
///
internal class LookupDbModel
{
+ public string Schema { get; set; }
public IList Lookups { get; set; }
public IList References { get; set; }
}
diff --git a/EfEnumToLookup/LookupGenerator/LookupValue.cs b/EfEnumToLookup/LookupGenerator/LookupValue.cs
index ac1c0ae..4b62398 100644
--- a/EfEnumToLookup/LookupGenerator/LookupValue.cs
+++ b/EfEnumToLookup/LookupGenerator/LookupValue.cs
@@ -4,5 +4,6 @@ internal class LookupValue
{
public int Id { get; set; }
public string Name { get; set; }
- }
+ public string Description { get; set; }
+ }
}
diff --git a/EfEnumToLookup/LookupGenerator/SqlServerHandler.cs b/EfEnumToLookup/LookupGenerator/SqlServerHandler.cs
index 7830b6b..8dea874 100644
--- a/EfEnumToLookup/LookupGenerator/SqlServerHandler.cs
+++ b/EfEnumToLookup/LookupGenerator/SqlServerHandler.cs
@@ -13,12 +13,18 @@ class SqlServerHandler : IDbHandler
///
public int NameFieldLength { get; set; }
- ///
- /// Prefix to add to all the generated tables to separate help group them together
- /// and make them stand out as different from other tables.
- /// Defaults to "Enum_" set to null or "" to not have any prefix.
+ ///
+ /// The size of the Description field that will be added to the generated lookup tables.
+ /// Adjust to suit your data if required, defaults to 255.
///
- public string TableNamePrefix { get; set; }
+ public int DescriptionFieldLength { get; set; }
+
+ ///
+ /// Prefix to add to all the generated tables to separate help group them together
+ /// and make them stand out as different from other tables.
+ /// Defaults to "Enum_" set to null or "" to not have any prefix.
+ ///
+ public string TableNamePrefix { get; set; }
///
/// Suffix to add to all the generated tables to separate help group them together
@@ -45,32 +51,33 @@ private string BuildSql(LookupDbModel model)
sql.AppendLine("set nocount on;");
sql.AppendLine("set xact_abort on; -- rollback on error");
sql.AppendLine("begin tran;");
- sql.AppendLine(CreateTables(model.Lookups));
- sql.AppendLine(PopulateLookups(model.Lookups));
- sql.AppendLine(AddForeignKeys(model.References));
+ sql.AppendLine(CreateTables(model.Lookups, model.Schema));
+ sql.AppendLine(PopulateLookups(model.Lookups, model.Schema));
+ sql.AppendLine(AddForeignKeys(model.References, model.Schema));
sql.AppendLine("commit;");
return sql.ToString();
}
- private string CreateTables(IEnumerable enums)
+ private string CreateTables(IEnumerable enums, string schema)
{
var sql = new StringBuilder();
+
foreach (var lookup in enums)
- {
+ {
sql.AppendFormat(
- @"IF OBJECT_ID('{0}', 'U') IS NULL
+ @"IF OBJECT_ID('{0}', 'U') IS NULL
begin
- CREATE TABLE [{0}] (Id {2} CONSTRAINT PK_{0} PRIMARY KEY, Name nvarchar({1}));
- exec sys.sp_addextendedproperty @name=N'MS_Description', @level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE',
+ CREATE TABLE [{4}].[{0}] (Id {2} CONSTRAINT PK_{0} PRIMARY KEY, Name nvarchar({1}), Description nvarchar({3}));
+ exec sys.sp_addextendedproperty @name=N'MS_Description', @level0type=N'SCHEMA', @level0name=N'{4}', @level1type=N'TABLE',
@level1name=N'{0}', @value=N'Automatically generated. Contents will be overwritten on app startup. Table & contents generated by https://github.com/timabell/ef-enum-to-lookup';
end
",
- TableName(lookup.Name), NameFieldLength, NumericSqlType(lookup.NumericType));
+ TableName(lookup.Name), NameFieldLength, NumericSqlType(lookup.NumericType), DescriptionFieldLength, schema);
}
return sql.ToString();
}
- private string AddForeignKeys(IEnumerable refs)
+ private string AddForeignKeys(IEnumerable refs, string schema)
{
var sql = new StringBuilder();
foreach (var enumReference in refs)
@@ -78,45 +85,44 @@ private string AddForeignKeys(IEnumerable refs)
var fkName = string.Format("FK_{0}_{1}", enumReference.ReferencingTable, enumReference.ReferencingField);
sql.AppendFormat(
- " IF OBJECT_ID('{0}', 'F') IS NULL ALTER TABLE [{1}] ADD CONSTRAINT {0} FOREIGN KEY ([{2}]) REFERENCES [{3}] (Id);\r\n",
- fkName, enumReference.ReferencingTable, enumReference.ReferencingField, TableName(enumReference.EnumType.Name)
- );
+ " IF OBJECT_ID('{0}', 'F') IS NULL ALTER TABLE [{4}].[{1}] ADD CONSTRAINT {0} FOREIGN KEY ([{2}]) REFERENCES [{4}].[{3}] (Id);\r\n",
+ fkName, enumReference.ReferencingTable, enumReference.ReferencingField, TableName(enumReference.EnumType.Name), schema);
}
return sql.ToString();
}
- private string PopulateLookups(IEnumerable lookupData)
+ private string PopulateLookups(IEnumerable lookupData, string schema)
{
var sql = new StringBuilder();
- sql.AppendLine(string.Format("CREATE TABLE #lookups (Id int, Name nvarchar({0}) COLLATE database_default);", NameFieldLength));
+ sql.AppendLine(string.Format("CREATE TABLE #lookups (Id int, Name nvarchar({0}), Description nvarchar({1}) COLLATE database_default);", NameFieldLength, DescriptionFieldLength));
foreach (var lookup in lookupData)
{
- sql.AppendLine(PopulateLookup(lookup));
+ sql.AppendLine(PopulateLookup(lookup, schema));
}
sql.AppendLine("DROP TABLE #lookups;");
return sql.ToString();
}
- private string PopulateLookup(LookupData lookup)
+ private string PopulateLookup(LookupData lookup, string schema)
{
var sql = new StringBuilder();
foreach (var value in lookup.Values)
{
- sql.AppendFormat("INSERT INTO #lookups (Id, Name) VALUES ({0}, N'{1}');\r\n", value.Id, SanitizeSqlString(value.Name));
+ sql.AppendFormat("INSERT INTO #lookups (Id, Name, Description) VALUES ({0}, N'{1}', N'{2}');\r\n", value.Id, SanitizeSqlString(value.Name), SanitizeSqlString(value.Description));
}
sql.AppendLine(string.Format(@"
-MERGE INTO [{0}] dst
+MERGE INTO [{1}].[{0}] dst
USING #lookups src ON src.Id = dst.Id
WHEN MATCHED AND src.Name <> dst.Name THEN
UPDATE SET Name = src.Name
WHEN NOT MATCHED THEN
- INSERT (Id, Name)
- VALUES (src.Id, src.Name)
+ INSERT (Id, Name, Description)
+ VALUES (src.Id, src.Name, src.Description)
WHEN NOT MATCHED BY SOURCE THEN
DELETE
;"
- , TableName(lookup.Name)));
+ , TableName(lookup.Name), schema));
sql.AppendLine("TRUNCATE TABLE #lookups;");
return sql.ToString();
@@ -124,7 +130,7 @@ WHEN NOT MATCHED BY SOURCE THEN
private static string SanitizeSqlString(string value)
{
- return value.Replace("'", "''");
+ return value == null ? null : value.Replace("'", "''");
}
private string TableName(string enumName)
diff --git a/EfEnumToLookup/Properties/AssemblyInfo.cs b/EfEnumToLookup/Properties/AssemblyInfo.cs
index 69eb094..04fba4a 100644
--- a/EfEnumToLookup/Properties/AssemblyInfo.cs
+++ b/EfEnumToLookup/Properties/AssemblyInfo.cs
@@ -33,6 +33,6 @@
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.8.0.0")]
+[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly:InternalsVisibleTo("EfEnumToLookupTests,PublicKey=002400000480000094000000060200000024000052534131000400000100010099a4b9a877a10f75bc4c1a9bf08ee9e21a2df3b9746f2535505b77b3f82971aa8a07caa6cd60b9df6e4b2982ebdb78da960ec1e7688a3b56b6da65e05783ee51f345b1cf0e5a38a02f3cc7c1763d7e469edafc59ef8c21b1a9bcca8548973429577362d992e4a6ed001cb28dc54ecc7ef298e94676bd918fd9e9b521e0cb7ae5")]
diff --git a/EfEnumToLookupTests/App.config b/EfEnumToLookupTests/App.config
index 047f1c8..7643ed3 100644
--- a/EfEnumToLookupTests/App.config
+++ b/EfEnumToLookupTests/App.config
@@ -10,7 +10,7 @@
-
+
diff --git a/EfEnumToLookupTests/EfEnumToLookupTests.csproj b/EfEnumToLookupTests/EfEnumToLookupTests.csproj
index c1764a2..b202401 100644
--- a/EfEnumToLookupTests/EfEnumToLookupTests.csproj
+++ b/EfEnumToLookupTests/EfEnumToLookupTests.csproj
@@ -100,6 +100,9 @@
EfEnumToLookup
+
+
+