diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.sln b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.sln
index 47fd8ef..74998e6 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.sln
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.sln
@@ -10,6 +10,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetallicBlueDev.EntityGate", "MetallicBlueDev.EntityGate\MetallicBlueDev.EntityGate.csproj", "{1898D29F-7FE8-4C29-A6FF-57860703D4D0}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetallicBlueDev.Sample.EntityGate", "MetallicBlueDev.Sample.EntityGate\MetallicBlueDev.Sample.EntityGate.csproj", "{CD267A11-4D5F-4AA9-B411-29E630681909}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetallicBlueDev.Sample.Data", "MetallicBlueDev.Sample.Data\MetallicBlueDev.Sample.Data.csproj", "{52F9655C-6895-4FBC-B3D2-F50EA9CC5356}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -20,6 +24,14 @@ Global
{1898D29F-7FE8-4C29-A6FF-57860703D4D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1898D29F-7FE8-4C29-A6FF-57860703D4D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1898D29F-7FE8-4C29-A6FF-57860703D4D0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CD267A11-4D5F-4AA9-B411-29E630681909}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CD267A11-4D5F-4AA9-B411-29E630681909}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CD267A11-4D5F-4AA9-B411-29E630681909}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CD267A11-4D5F-4AA9-B411-29E630681909}.Release|Any CPU.Build.0 = Release|Any CPU
+ {52F9655C-6895-4FBC-B3D2-F50EA9CC5356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {52F9655C-6895-4FBC-B3D2-F50EA9CC5356}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {52F9655C-6895-4FBC-B3D2-F50EA9CC5356}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {52F9655C-6895-4FBC-B3D2-F50EA9CC5356}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/ClientConfiguration.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/ClientConfiguration.cs
index f772874..5bd0871 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/ClientConfiguration.cs
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/ClientConfiguration.cs
@@ -104,7 +104,7 @@ public int Timeout
///
/// If the main entity implements the interface, the backup is automatically enabled.
///
- public bool AutomaticCheckOfOriginValues { get; set; }
+ public bool AutomaticCheckOfOriginalValues { get; set; }
///
/// Log internal messages. Include messages from Entity Framework.
@@ -143,10 +143,7 @@ public void ChangeConnectionString(string connectionName)
if (currentConfig != null)
{
- MaximumNumberOfAttempts = currentConfig.MaximumNumberOfAttempts;
- AttemptDelay = currentConfig.AttemptDelay;
- LazyLoading = currentConfig.LazyLoading;
- ConnectionString = EntityGateConfigLoader.GetConnectionString(currentConfig.ConnectionName);
+ CopyConfiguration(currentConfig);
if (CanUseLogging)
{
@@ -205,6 +202,21 @@ internal void ConfigurationUpdated()
}
}
+ ///
+ /// Copy of the configuration.
+ ///
+ ///
+ private void CopyConfiguration(EntityGateConfig config)
+ {
+ ConnectionString = EntityGateConfigLoader.GetConnectionString(config.ConnectionName);
+
+ MaximumNumberOfAttempts = config.MaximumNumberOfAttempts;
+ AttemptDelay = config.AttemptDelay;
+ LazyLoading = config.LazyLoading;
+ Timeout = config.Timeout;
+ AutomaticCheckOfOriginalValues = config.AutomaticCheckOfOriginalValues;
+ }
+
///
/// Indicates that the context is synchronized to this configuration.
///
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/EntityGateConfig.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/EntityGateConfig.cs
index 38372bd..3607ccb 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/EntityGateConfig.cs
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Configuration/EntityGateConfig.cs
@@ -34,6 +34,6 @@ internal class EntityGateConfig
///
/// Determines if the backup of the original values is performed automatically.
///
- internal bool AutomaticCheckOfOriginValues { get; set; } = true;
+ internal bool AutomaticCheckOfOriginalValues { get; set; } = true;
}
}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Core/EntityGateCore.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Core/EntityGateCore.cs
index eca5e51..0ac79eb 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Core/EntityGateCore.cs
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Core/EntityGateCore.cs
@@ -1132,7 +1132,7 @@ private void FireAutoSaveOriginalValues()
///
private void CheckEntityForAutoSaveOriginalValues()
{
- if (Configuration.AutomaticCheckOfOriginValues)
+ if (Configuration.AutomaticCheckOfOriginalValues)
{
var oldState = Token.SaveOriginalValues;
var newState = entity.IsEntityArchival();
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.csproj b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.csproj
index 4eacd19..f575120 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.csproj
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate.csproj
@@ -83,9 +83,6 @@
-
-
-
6.3.0
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Properties/AssemblyInfo.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Properties/AssemblyInfo.cs
index 9f71371..c544c73 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Properties/AssemblyInfo.cs
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/Properties/AssemblyInfo.cs
@@ -6,11 +6,11 @@
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MetallicBlueDev.EntityGate")]
-[assembly: AssemblyDescription("")]
+[assembly: AssemblyDescription("EntityGate")]
[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
+[assembly: AssemblyCompany("MetallicBlueDev")]
[assembly: AssemblyProduct("MetallicBlueDev.EntityGate")]
-[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyCopyright("MetallicBlueDev")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("1.0.1.0")]
+[assembly: AssemblyFileVersion("1.0.1.0")]
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/App.Config b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/App.Config
new file mode 100644
index 0000000..a386060
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/App.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/MetallicBlueDev.Sample.Data.csproj b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/MetallicBlueDev.Sample.Data.csproj
new file mode 100644
index 0000000..b6bfc48
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/MetallicBlueDev.Sample.Data.csproj
@@ -0,0 +1,111 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {52F9655C-6895-4FBC-B3D2-F50EA9CC5356}
+ Library
+ Properties
+ MetallicBlueDev.Sample.Data
+ MetallicBlueDev.Sample.Data
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SampleData.tt
+
+
+
+ True
+ True
+ SampleData.Context.tt
+
+
+ True
+ True
+ SampleData.tt
+
+
+ True
+ True
+ SampleData.edmx
+
+
+ SampleData.tt
+
+
+
+
+ EntityModelCodeGenerator
+ SampleData.Designer.cs
+
+
+
+
+
+ SampleData.edmx
+
+
+
+
+ TextTemplatingFileGenerator
+ SampleData.Context.cs
+ SampleData.edmx
+
+
+
+ TextTemplatingFileGenerator
+ SampleData.cs
+ SampleData.edmx
+
+
+
+
+
+
+
+ 6.3.0
+
+
+
+
+ {1898D29F-7FE8-4C29-A6FF-57860703D4D0}
+ MetallicBlueDev.EntityGate
+
+
+
+
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/OtherEntity.Interface.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/OtherEntity.Interface.cs
new file mode 100644
index 0000000..53598e4
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/OtherEntity.Interface.cs
@@ -0,0 +1,12 @@
+using MetallicBlueDev.EntityGate.InterfacedObject;
+
+namespace MetallicBlueDev.Sample.Data
+{
+ public partial class OtherEntity : IEntityObjectIdentifier
+ {
+ ///
+ /// Mandatory implementation of the interface.
+ ///
+ public object Identifier => Id;
+ }
+}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/OtherEntity.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/OtherEntity.cs
new file mode 100644
index 0000000..2f48385
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/OtherEntity.cs
@@ -0,0 +1,17 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated from a template.
+//
+// Manual changes to this file may cause unexpected behavior in your application.
+// Manual changes to this file will be overwritten if the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MetallicBlueDev.Sample.Data
+{
+ public partial class OtherEntity
+ {
+ public int Id { get; set; }
+ public string Description { get; set; }
+ }
+}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/Properties/AssemblyInfo.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..113e79e
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MetallicBlueDev.Sample.Data")]
+[assembly: AssemblyDescription("Sample.Data")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MetallicBlueDev")]
+[assembly: AssemblyProduct("MetallicBlueDev.Sample.Data")]
+[assembly: AssemblyCopyright("MetallicBlueDev")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("52f9655c-6895-4fbc-b3d2-f50ea9cc5356")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Context.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Context.cs
new file mode 100644
index 0000000..e2169fc
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Context.cs
@@ -0,0 +1,31 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated from a template.
+//
+// Manual changes to this file may cause unexpected behavior in your application.
+// Manual changes to this file will be overwritten if the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MetallicBlueDev.Sample.Data
+{
+ using System;
+ using System.Data.Entity;
+ using System.Data.Entity.Infrastructure;
+
+ public partial class SampleDataContainer : DbContext
+ {
+ public SampleDataContainer()
+ : base("name=SampleDataContainer")
+ {
+ }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ throw new UnintentionalCodeFirstException();
+ }
+
+ public virtual DbSet SampleEntity1Set { get; set; }
+ public virtual DbSet OtherEntitySet { get; set; }
+ }
+}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Context.tt b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Context.tt
new file mode 100644
index 0000000..667e2ba
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Context.tt
@@ -0,0 +1,636 @@
+<#@ template language="C#" debug="false" hostspecific="true"#>
+<#@ include file="EF6.Utility.CS.ttinclude"#><#@
+ output extension=".cs"#><#
+
+const string inputFile = @"SampleData.edmx";
+var textTransform = DynamicTextTransformation.Create(this);
+var code = new CodeGenerationTools(this);
+var ef = new MetadataTools(this);
+var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
+var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
+var itemCollection = loader.CreateEdmItemCollection(inputFile);
+var modelNamespace = loader.GetModelNamespace(inputFile);
+var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
+
+var container = itemCollection.OfType().FirstOrDefault();
+if (container == null)
+{
+ return string.Empty;
+}
+#>
+//------------------------------------------------------------------------------
+//
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
+//
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
+//
+//------------------------------------------------------------------------------
+
+<#
+
+var codeNamespace = code.VsNamespaceSuggestion();
+if (!String.IsNullOrEmpty(codeNamespace))
+{
+#>
+namespace <#=code.EscapeNamespace(codeNamespace)#>
+{
+<#
+ PushIndent(" ");
+}
+
+#>
+using System;
+using System.Data.Entity;
+using System.Data.Entity.Infrastructure;
+<#
+if (container.FunctionImports.Any())
+{
+#>
+using System.Data.Entity.Core.Objects;
+using System.Linq;
+<#
+}
+#>
+
+<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
+{
+ public <#=code.Escape(container)#>()
+ : base("name=<#=container.Name#>")
+ {
+<#
+if (!loader.IsLazyLoadingEnabled(container))
+{
+#>
+ this.Configuration.LazyLoadingEnabled = false;
+<#
+}
+
+foreach (var entitySet in container.BaseEntitySets.OfType())
+{
+ // Note: the DbSet members are defined below such that the getter and
+ // setter always have the same accessibility as the DbSet definition
+ if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
+ {
+#>
+ <#=codeStringGenerator.DbSetInitializer(entitySet)#>
+<#
+ }
+}
+#>
+ }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ throw new UnintentionalCodeFirstException();
+ }
+
+<#
+ foreach (var entitySet in container.BaseEntitySets.OfType())
+ {
+#>
+ <#=codeStringGenerator.DbSet(entitySet)#>
+<#
+ }
+
+ foreach (var edmFunction in container.FunctionImports)
+ {
+ WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
+ }
+#>
+}
+<#
+
+if (!String.IsNullOrEmpty(codeNamespace))
+{
+ PopIndent();
+#>
+}
+<#
+}
+#>
+<#+
+
+private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
+{
+ if (typeMapper.IsComposable(edmFunction))
+ {
+#>
+
+ [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
+ <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
+ {
+<#+
+ codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
+#>
+ <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
+ }
+<#+
+ }
+ else
+ {
+#>
+
+ <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
+ {
+<#+
+ codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
+#>
+ <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
+ }
+<#+
+ if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
+ {
+ WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
+ }
+ }
+}
+
+public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
+{
+#>
+ var <#=name#> = <#=isNotNull#> ?
+ <#=notNullInit#> :
+ <#=nullInit#>;
+
+<#+
+}
+
+public const string TemplateId = "CSharp_DbContext_Context_EF6";
+
+public class CodeStringGenerator
+{
+ private readonly CodeGenerationTools _code;
+ private readonly TypeMapper _typeMapper;
+ private readonly MetadataTools _ef;
+
+ public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
+ {
+ ArgumentNotNull(code, "code");
+ ArgumentNotNull(typeMapper, "typeMapper");
+ ArgumentNotNull(ef, "ef");
+
+ _code = code;
+ _typeMapper = typeMapper;
+ _ef = ef;
+ }
+
+ public string Property(EdmProperty edmProperty)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1} {2} {{ {3}get; {4}set; }}",
+ Accessibility.ForProperty(edmProperty),
+ _typeMapper.GetTypeName(edmProperty.TypeUsage),
+ _code.Escape(edmProperty),
+ _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
+ _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
+ }
+
+ public string NavigationProperty(NavigationProperty navProp)
+ {
+ var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1} {2} {{ {3}get; {4}set; }}",
+ AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
+ navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
+ _code.Escape(navProp),
+ _code.SpaceAfter(Accessibility.ForGetter(navProp)),
+ _code.SpaceAfter(Accessibility.ForSetter(navProp)));
+ }
+
+ public string AccessibilityAndVirtual(string accessibility)
+ {
+ return accessibility + (accessibility != "private" ? " virtual" : "");
+ }
+
+ public string EntityClassOpening(EntityType entity)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1}partial class {2}{3}",
+ Accessibility.ForType(entity),
+ _code.SpaceAfter(_code.AbstractOption(entity)),
+ _code.Escape(entity),
+ _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
+ }
+
+ public string EnumOpening(SimpleType enumType)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} enum {1} : {2}",
+ Accessibility.ForType(enumType),
+ _code.Escape(enumType),
+ _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
+ }
+
+ public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
+ {
+ var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
+ foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
+ {
+ var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
+ var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
+ var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
+ writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
+ }
+ }
+
+ public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} IQueryable<{1}> {2}({3})",
+ AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
+ _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
+ _code.Escape(edmFunction),
+ string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
+ }
+
+ public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
+ _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
+ edmFunction.NamespaceName,
+ edmFunction.Name,
+ string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
+ _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
+ }
+
+ public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+ var returnType = _typeMapper.GetReturnType(edmFunction);
+
+ var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
+ if (includeMergeOption)
+ {
+ paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
+ }
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1} {2}({3})",
+ AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
+ returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
+ _code.Escape(edmFunction),
+ paramList);
+ }
+
+ public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+ var returnType = _typeMapper.GetReturnType(edmFunction);
+
+ var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
+ if (includeMergeOption)
+ {
+ callParams = ", mergeOption" + callParams;
+ }
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
+ returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
+ edmFunction.Name,
+ callParams);
+ }
+
+ public string DbSet(EntitySet entitySet)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
+ Accessibility.ForReadOnlyProperty(entitySet),
+ _typeMapper.GetTypeName(entitySet.ElementType),
+ _code.Escape(entitySet));
+ }
+
+ public string DbSetInitializer(EntitySet entitySet)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} = Set<{1}>();",
+ _code.Escape(entitySet),
+ _typeMapper.GetTypeName(entitySet.ElementType));
+ }
+
+ public string UsingDirectives(bool inHeader, bool includeCollections = true)
+ {
+ return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
+ ? string.Format(
+ CultureInfo.InvariantCulture,
+ "{0}using System;{1}" +
+ "{2}",
+ inHeader ? Environment.NewLine : "",
+ includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
+ inHeader ? "" : Environment.NewLine)
+ : "";
+ }
+}
+
+public class TypeMapper
+{
+ private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
+
+ private readonly System.Collections.IList _errors;
+ private readonly CodeGenerationTools _code;
+ private readonly MetadataTools _ef;
+
+ public static string FixNamespaces(string typeName)
+ {
+ return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
+ }
+
+ public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
+ {
+ ArgumentNotNull(code, "code");
+ ArgumentNotNull(ef, "ef");
+ ArgumentNotNull(errors, "errors");
+
+ _code = code;
+ _ef = ef;
+ _errors = errors;
+ }
+
+ public string GetTypeName(TypeUsage typeUsage)
+ {
+ return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
+ }
+
+ public string GetTypeName(EdmType edmType)
+ {
+ return GetTypeName(edmType, isNullable: null, modelNamespace: null);
+ }
+
+ public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
+ {
+ return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
+ }
+
+ public string GetTypeName(EdmType edmType, string modelNamespace)
+ {
+ return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
+ }
+
+ public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
+ {
+ if (edmType == null)
+ {
+ return null;
+ }
+
+ var collectionType = edmType as CollectionType;
+ if (collectionType != null)
+ {
+ return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
+ }
+
+ var typeName = _code.Escape(edmType.MetadataProperties
+ .Where(p => p.Name == ExternalTypeNameAttributeName)
+ .Select(p => (string)p.Value)
+ .FirstOrDefault())
+ ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
+ _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
+ _code.Escape(edmType));
+
+ if (edmType is StructuralType)
+ {
+ return typeName;
+ }
+
+ if (edmType is SimpleType)
+ {
+ var clrType = UnderlyingClrType(edmType);
+ if (!IsEnumType(edmType))
+ {
+ typeName = _code.Escape(clrType);
+ }
+
+ typeName = FixNamespaces(typeName);
+
+ return clrType.IsValueType && isNullable == true ?
+ String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
+ typeName;
+ }
+
+ throw new ArgumentException("edmType");
+ }
+
+ public Type UnderlyingClrType(EdmType edmType)
+ {
+ ArgumentNotNull(edmType, "edmType");
+
+ var primitiveType = edmType as PrimitiveType;
+ if (primitiveType != null)
+ {
+ return primitiveType.ClrEquivalentType;
+ }
+
+ if (IsEnumType(edmType))
+ {
+ return GetEnumUnderlyingType(edmType).ClrEquivalentType;
+ }
+
+ return typeof(object);
+ }
+
+ public object GetEnumMemberValue(MetadataItem enumMember)
+ {
+ ArgumentNotNull(enumMember, "enumMember");
+
+ var valueProperty = enumMember.GetType().GetProperty("Value");
+ return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
+ }
+
+ public string GetEnumMemberName(MetadataItem enumMember)
+ {
+ ArgumentNotNull(enumMember, "enumMember");
+
+ var nameProperty = enumMember.GetType().GetProperty("Name");
+ return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
+ }
+
+ public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
+ {
+ ArgumentNotNull(enumType, "enumType");
+
+ var membersProperty = enumType.GetType().GetProperty("Members");
+ return membersProperty != null
+ ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
+ : Enumerable.Empty();
+ }
+
+ public bool EnumIsFlags(EdmType enumType)
+ {
+ ArgumentNotNull(enumType, "enumType");
+
+ var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
+ return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
+ }
+
+ public bool IsEnumType(GlobalItem edmType)
+ {
+ ArgumentNotNull(edmType, "edmType");
+
+ return edmType.GetType().Name == "EnumType";
+ }
+
+ public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
+ {
+ ArgumentNotNull(enumType, "enumType");
+
+ return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
+ }
+
+ public string CreateLiteral(object value)
+ {
+ if (value == null || value.GetType() != typeof(TimeSpan))
+ {
+ return _code.CreateLiteral(value);
+ }
+
+ return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
+ }
+
+ public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
+ {
+ ArgumentNotNull(types, "types");
+ ArgumentNotNull(sourceFile, "sourceFile");
+
+ var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
+ if (types.Any(item => !hash.Add(item)))
+ {
+ _errors.Add(
+ new CompilerError(sourceFile, -1, -1, "6023",
+ String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
+ return false;
+ }
+ return true;
+ }
+
+ public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
+ {
+ return GetItemsToGenerate(itemCollection)
+ .Where(e => IsEnumType(e));
+ }
+
+ public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
+ {
+ return itemCollection
+ .OfType()
+ .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
+ .OrderBy(i => i.Name);
+ }
+
+ public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
+ {
+ return itemCollection
+ .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
+ .Select(g => GetGlobalItemName(g));
+ }
+
+ public string GetGlobalItemName(GlobalItem item)
+ {
+ if (item is EdmType)
+ {
+ return ((EdmType)item).Name;
+ }
+ else
+ {
+ return ((EntityContainer)item).Name;
+ }
+ }
+
+ public IEnumerable GetSimpleProperties(EntityType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetSimpleProperties(ComplexType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetComplexProperties(EntityType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetComplexProperties(ComplexType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
+ }
+
+ public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
+ }
+
+ public IEnumerable GetNavigationProperties(EntityType type)
+ {
+ return type.NavigationProperties.Where(np => np.DeclaringType == type);
+ }
+
+ public IEnumerable GetCollectionNavigationProperties(EntityType type)
+ {
+ return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
+ }
+
+ public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
+ {
+ ArgumentNotNull(edmFunction, "edmFunction");
+
+ var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
+ return returnParamsProperty == null
+ ? edmFunction.ReturnParameter
+ : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
+ }
+
+ public bool IsComposable(EdmFunction edmFunction)
+ {
+ ArgumentNotNull(edmFunction, "edmFunction");
+
+ var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
+ return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
+ }
+
+ public IEnumerable GetParameters(EdmFunction edmFunction)
+ {
+ return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
+ }
+
+ public TypeUsage GetReturnType(EdmFunction edmFunction)
+ {
+ var returnParam = GetReturnParameter(edmFunction);
+ return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
+ }
+
+ public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
+ {
+ var returnType = GetReturnType(edmFunction);
+ return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
+ }
+}
+
+public static void ArgumentNotNull(T arg, string name) where T : class
+{
+ if (arg == null)
+ {
+ throw new ArgumentNullException(name);
+ }
+}
+#>
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Designer.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Designer.cs
new file mode 100644
index 0000000..87bb231
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.Designer.cs
@@ -0,0 +1,10 @@
+// T4 code generation is enabled for model 'L:\Repos\MetallicBlueDev\EntityGate\MetallicBlueDev.EntityGate\MetallicBlueDev.Sample.Data\SampleData.edmx'.
+// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
+// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
+// is open in the designer.
+
+// If no context and entity classes have been generated, it may be because you created an empty model but
+// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
+// classes for your model, open the model in the designer, right-click on the designer surface, and
+// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
+// Item...'.
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.cs
new file mode 100644
index 0000000..7cc0662
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.cs
@@ -0,0 +1,9 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated from a template.
+//
+// Manual changes to this file may cause unexpected behavior in your application.
+// Manual changes to this file will be overwritten if the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx
new file mode 100644
index 0000000..1108d4e
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx.diagram b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx.diagram
new file mode 100644
index 0000000..8e72980
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx.diagram
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx.sql b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx.sql
new file mode 100644
index 0000000..1a6f9ae
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.edmx.sql
@@ -0,0 +1,66 @@
+
+-- --------------------------------------------------
+-- Entity Designer DDL Script for SQL Server 2005, 2008, 2012 and Azure
+-- --------------------------------------------------
+-- Date Created: 10/26/2019 16:10:40
+-- Generated from EDMX file: L:\Repos\MetallicBlueDev\EntityGate\MetallicBlueDev.EntityGate\MetallicBlueDev.Sample.Data\SampleData.edmx
+-- --------------------------------------------------
+
+SET QUOTED_IDENTIFIER OFF;
+GO
+USE [SampleDbTest];
+GO
+IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
+GO
+
+-- --------------------------------------------------
+-- Dropping existing FOREIGN KEY constraints
+-- --------------------------------------------------
+
+
+-- --------------------------------------------------
+-- Dropping existing tables
+-- --------------------------------------------------
+
+
+-- --------------------------------------------------
+-- Creating all tables
+-- --------------------------------------------------
+
+-- Creating table 'SampleEntity1Set'
+CREATE TABLE [dbo].[SampleEntity1Set] (
+ [Id] int IDENTITY(1,1) NOT NULL,
+ [Value] int NOT NULL
+);
+GO
+
+-- Creating table 'OtherEntitySet'
+CREATE TABLE [dbo].[OtherEntitySet] (
+ [Id] int IDENTITY(1,1) NOT NULL,
+ [Description] nvarchar(max) NOT NULL
+);
+GO
+
+-- --------------------------------------------------
+-- Creating all PRIMARY KEY constraints
+-- --------------------------------------------------
+
+-- Creating primary key on [Id] in table 'SampleEntity1Set'
+ALTER TABLE [dbo].[SampleEntity1Set]
+ADD CONSTRAINT [PK_SampleEntity1Set]
+ PRIMARY KEY CLUSTERED ([Id] ASC);
+GO
+
+-- Creating primary key on [Id] in table 'OtherEntitySet'
+ALTER TABLE [dbo].[OtherEntitySet]
+ADD CONSTRAINT [PK_OtherEntitySet]
+ PRIMARY KEY CLUSTERED ([Id] ASC);
+GO
+
+-- --------------------------------------------------
+-- Creating all FOREIGN KEY constraints
+-- --------------------------------------------------
+
+-- --------------------------------------------------
+-- Script has ended
+-- --------------------------------------------------
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.tt b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.tt
new file mode 100644
index 0000000..e8fab0b
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleData.tt
@@ -0,0 +1,733 @@
+<#@ template language="C#" debug="false" hostspecific="true"#>
+<#@ include file="EF6.Utility.CS.ttinclude"#><#@
+ output extension=".cs"#><#
+
+const string inputFile = @"SampleData.edmx";
+var textTransform = DynamicTextTransformation.Create(this);
+var code = new CodeGenerationTools(this);
+var ef = new MetadataTools(this);
+var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
+var fileManager = EntityFrameworkTemplateFileManager.Create(this);
+var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
+var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
+
+if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
+{
+ return string.Empty;
+}
+
+WriteHeader(codeStringGenerator, fileManager);
+
+foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection))
+{
+ fileManager.StartNewFile(entity.Name + ".cs");
+ BeginNamespace(code);
+#>
+<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
+<#=codeStringGenerator.EntityClassOpening(entity)#>
+{
+<#
+ var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
+ var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
+ var complexProperties = typeMapper.GetComplexProperties(entity);
+
+ if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
+ {
+#>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
+ public <#=code.Escape(entity)#>()
+ {
+<#
+ foreach (var edmProperty in propertiesWithDefaultValues)
+ {
+#>
+ this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
+<#
+ }
+
+ foreach (var navigationProperty in collectionNavigationProperties)
+ {
+#>
+ this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
+<#
+ }
+
+ foreach (var complexProperty in complexProperties)
+ {
+#>
+ this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
+<#
+ }
+#>
+ }
+
+<#
+ }
+
+ var simpleProperties = typeMapper.GetSimpleProperties(entity);
+ if (simpleProperties.Any())
+ {
+ foreach (var edmProperty in simpleProperties)
+ {
+#>
+ <#=codeStringGenerator.Property(edmProperty)#>
+<#
+ }
+ }
+
+ if (complexProperties.Any())
+ {
+#>
+
+<#
+ foreach(var complexProperty in complexProperties)
+ {
+#>
+ <#=codeStringGenerator.Property(complexProperty)#>
+<#
+ }
+ }
+
+ var navigationProperties = typeMapper.GetNavigationProperties(entity);
+ if (navigationProperties.Any())
+ {
+#>
+
+<#
+ foreach (var navigationProperty in navigationProperties)
+ {
+ if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
+ {
+#>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
+<#
+ }
+#>
+ <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
+<#
+ }
+ }
+#>
+}
+<#
+ EndNamespace(code);
+}
+
+foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection))
+{
+ fileManager.StartNewFile(complex.Name + ".cs");
+ BeginNamespace(code);
+#>
+<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
+<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
+{
+<#
+ var complexProperties = typeMapper.GetComplexProperties(complex);
+ var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
+
+ if (propertiesWithDefaultValues.Any() || complexProperties.Any())
+ {
+#>
+ public <#=code.Escape(complex)#>()
+ {
+<#
+ foreach (var edmProperty in propertiesWithDefaultValues)
+ {
+#>
+ this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
+<#
+ }
+
+ foreach (var complexProperty in complexProperties)
+ {
+#>
+ this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
+<#
+ }
+#>
+ }
+
+<#
+ }
+
+ var simpleProperties = typeMapper.GetSimpleProperties(complex);
+ if (simpleProperties.Any())
+ {
+ foreach(var edmProperty in simpleProperties)
+ {
+#>
+ <#=codeStringGenerator.Property(edmProperty)#>
+<#
+ }
+ }
+
+ if (complexProperties.Any())
+ {
+#>
+
+<#
+ foreach(var edmProperty in complexProperties)
+ {
+#>
+ <#=codeStringGenerator.Property(edmProperty)#>
+<#
+ }
+ }
+#>
+}
+<#
+ EndNamespace(code);
+}
+
+foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
+{
+ fileManager.StartNewFile(enumType.Name + ".cs");
+ BeginNamespace(code);
+#>
+<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
+<#
+ if (typeMapper.EnumIsFlags(enumType))
+ {
+#>
+[Flags]
+<#
+ }
+#>
+<#=codeStringGenerator.EnumOpening(enumType)#>
+{
+<#
+ var foundOne = false;
+
+ foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
+ {
+ foundOne = true;
+#>
+ <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
+<#
+ }
+
+ if (foundOne)
+ {
+ this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
+ }
+#>
+}
+<#
+ EndNamespace(code);
+}
+
+fileManager.Process();
+
+#>
+<#+
+
+public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
+{
+ fileManager.StartHeader();
+#>
+//------------------------------------------------------------------------------
+//
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
+//
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
+// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
+//
+//------------------------------------------------------------------------------
+<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
+<#+
+ fileManager.EndBlock();
+}
+
+public void BeginNamespace(CodeGenerationTools code)
+{
+ var codeNamespace = code.VsNamespaceSuggestion();
+ if (!String.IsNullOrEmpty(codeNamespace))
+ {
+#>
+namespace <#=code.EscapeNamespace(codeNamespace)#>
+{
+<#+
+ PushIndent(" ");
+ }
+}
+
+public void EndNamespace(CodeGenerationTools code)
+{
+ if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
+ {
+ PopIndent();
+#>
+}
+<#+
+ }
+}
+
+public const string TemplateId = "CSharp_DbContext_Types_EF6";
+
+public class CodeStringGenerator
+{
+ private readonly CodeGenerationTools _code;
+ private readonly TypeMapper _typeMapper;
+ private readonly MetadataTools _ef;
+
+ public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
+ {
+ ArgumentNotNull(code, "code");
+ ArgumentNotNull(typeMapper, "typeMapper");
+ ArgumentNotNull(ef, "ef");
+
+ _code = code;
+ _typeMapper = typeMapper;
+ _ef = ef;
+ }
+
+ public string Property(EdmProperty edmProperty)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1} {2} {{ {3}get; {4}set; }}",
+ Accessibility.ForProperty(edmProperty),
+ _typeMapper.GetTypeName(edmProperty.TypeUsage),
+ _code.Escape(edmProperty),
+ _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
+ _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
+ }
+
+ public string NavigationProperty(NavigationProperty navProp)
+ {
+ var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1} {2} {{ {3}get; {4}set; }}",
+ AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
+ navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
+ _code.Escape(navProp),
+ _code.SpaceAfter(Accessibility.ForGetter(navProp)),
+ _code.SpaceAfter(Accessibility.ForSetter(navProp)));
+ }
+
+ public string AccessibilityAndVirtual(string accessibility)
+ {
+ return accessibility + (accessibility != "private" ? " virtual" : "");
+ }
+
+ public string EntityClassOpening(EntityType entity)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1}partial class {2}{3}",
+ Accessibility.ForType(entity),
+ _code.SpaceAfter(_code.AbstractOption(entity)),
+ _code.Escape(entity),
+ _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
+ }
+
+ public string EnumOpening(SimpleType enumType)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} enum {1} : {2}",
+ Accessibility.ForType(enumType),
+ _code.Escape(enumType),
+ _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
+ }
+
+ public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
+ {
+ var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
+ foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
+ {
+ var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
+ var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
+ var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
+ writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
+ }
+ }
+
+ public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} IQueryable<{1}> {2}({3})",
+ AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
+ _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
+ _code.Escape(edmFunction),
+ string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
+ }
+
+ public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
+ _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
+ edmFunction.NamespaceName,
+ edmFunction.Name,
+ string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
+ _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
+ }
+
+ public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+ var returnType = _typeMapper.GetReturnType(edmFunction);
+
+ var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
+ if (includeMergeOption)
+ {
+ paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
+ }
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} {1} {2}({3})",
+ AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
+ returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
+ _code.Escape(edmFunction),
+ paramList);
+ }
+
+ public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
+ {
+ var parameters = _typeMapper.GetParameters(edmFunction);
+ var returnType = _typeMapper.GetReturnType(edmFunction);
+
+ var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
+ if (includeMergeOption)
+ {
+ callParams = ", mergeOption" + callParams;
+ }
+
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
+ returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
+ edmFunction.Name,
+ callParams);
+ }
+
+ public string DbSet(EntitySet entitySet)
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
+ Accessibility.ForReadOnlyProperty(entitySet),
+ _typeMapper.GetTypeName(entitySet.ElementType),
+ _code.Escape(entitySet));
+ }
+
+ public string UsingDirectives(bool inHeader, bool includeCollections = true)
+ {
+ return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
+ ? string.Format(
+ CultureInfo.InvariantCulture,
+ "{0}using System;{1}" +
+ "{2}",
+ inHeader ? Environment.NewLine : "",
+ includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
+ inHeader ? "" : Environment.NewLine)
+ : "";
+ }
+}
+
+public class TypeMapper
+{
+ private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
+
+ private readonly System.Collections.IList _errors;
+ private readonly CodeGenerationTools _code;
+ private readonly MetadataTools _ef;
+
+ public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
+ {
+ ArgumentNotNull(code, "code");
+ ArgumentNotNull(ef, "ef");
+ ArgumentNotNull(errors, "errors");
+
+ _code = code;
+ _ef = ef;
+ _errors = errors;
+ }
+
+ public static string FixNamespaces(string typeName)
+ {
+ return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
+ }
+
+ public string GetTypeName(TypeUsage typeUsage)
+ {
+ return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
+ }
+
+ public string GetTypeName(EdmType edmType)
+ {
+ return GetTypeName(edmType, isNullable: null, modelNamespace: null);
+ }
+
+ public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
+ {
+ return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
+ }
+
+ public string GetTypeName(EdmType edmType, string modelNamespace)
+ {
+ return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
+ }
+
+ public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
+ {
+ if (edmType == null)
+ {
+ return null;
+ }
+
+ var collectionType = edmType as CollectionType;
+ if (collectionType != null)
+ {
+ return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
+ }
+
+ var typeName = _code.Escape(edmType.MetadataProperties
+ .Where(p => p.Name == ExternalTypeNameAttributeName)
+ .Select(p => (string)p.Value)
+ .FirstOrDefault())
+ ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
+ _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
+ _code.Escape(edmType));
+
+ if (edmType is StructuralType)
+ {
+ return typeName;
+ }
+
+ if (edmType is SimpleType)
+ {
+ var clrType = UnderlyingClrType(edmType);
+ if (!IsEnumType(edmType))
+ {
+ typeName = _code.Escape(clrType);
+ }
+
+ typeName = FixNamespaces(typeName);
+
+ return clrType.IsValueType && isNullable == true ?
+ String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
+ typeName;
+ }
+
+ throw new ArgumentException("edmType");
+ }
+
+ public Type UnderlyingClrType(EdmType edmType)
+ {
+ ArgumentNotNull(edmType, "edmType");
+
+ var primitiveType = edmType as PrimitiveType;
+ if (primitiveType != null)
+ {
+ return primitiveType.ClrEquivalentType;
+ }
+
+ if (IsEnumType(edmType))
+ {
+ return GetEnumUnderlyingType(edmType).ClrEquivalentType;
+ }
+
+ return typeof(object);
+ }
+
+ public object GetEnumMemberValue(MetadataItem enumMember)
+ {
+ ArgumentNotNull(enumMember, "enumMember");
+
+ var valueProperty = enumMember.GetType().GetProperty("Value");
+ return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
+ }
+
+ public string GetEnumMemberName(MetadataItem enumMember)
+ {
+ ArgumentNotNull(enumMember, "enumMember");
+
+ var nameProperty = enumMember.GetType().GetProperty("Name");
+ return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
+ }
+
+ public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
+ {
+ ArgumentNotNull(enumType, "enumType");
+
+ var membersProperty = enumType.GetType().GetProperty("Members");
+ return membersProperty != null
+ ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
+ : Enumerable.Empty();
+ }
+
+ public bool EnumIsFlags(EdmType enumType)
+ {
+ ArgumentNotNull(enumType, "enumType");
+
+ var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
+ return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
+ }
+
+ public bool IsEnumType(GlobalItem edmType)
+ {
+ ArgumentNotNull(edmType, "edmType");
+
+ return edmType.GetType().Name == "EnumType";
+ }
+
+ public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
+ {
+ ArgumentNotNull(enumType, "enumType");
+
+ return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
+ }
+
+ public string CreateLiteral(object value)
+ {
+ if (value == null || value.GetType() != typeof(TimeSpan))
+ {
+ return _code.CreateLiteral(value);
+ }
+
+ return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
+ }
+
+ public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
+ {
+ ArgumentNotNull(types, "types");
+ ArgumentNotNull(sourceFile, "sourceFile");
+
+ var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
+ if (types.Any(item => !hash.Add(item)))
+ {
+ _errors.Add(
+ new CompilerError(sourceFile, -1, -1, "6023",
+ String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
+ return false;
+ }
+ return true;
+ }
+
+ public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
+ {
+ return GetItemsToGenerate(itemCollection)
+ .Where(e => IsEnumType(e));
+ }
+
+ public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
+ {
+ return itemCollection
+ .OfType()
+ .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
+ .OrderBy(i => i.Name);
+ }
+
+ public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
+ {
+ return itemCollection
+ .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
+ .Select(g => GetGlobalItemName(g));
+ }
+
+ public string GetGlobalItemName(GlobalItem item)
+ {
+ if (item is EdmType)
+ {
+ return ((EdmType)item).Name;
+ }
+ else
+ {
+ return ((EntityContainer)item).Name;
+ }
+ }
+
+ public IEnumerable GetSimpleProperties(EntityType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetSimpleProperties(ComplexType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetComplexProperties(EntityType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetComplexProperties(ComplexType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
+ }
+
+ public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
+ }
+
+ public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
+ {
+ return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
+ }
+
+ public IEnumerable GetNavigationProperties(EntityType type)
+ {
+ return type.NavigationProperties.Where(np => np.DeclaringType == type);
+ }
+
+ public IEnumerable GetCollectionNavigationProperties(EntityType type)
+ {
+ return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
+ }
+
+ public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
+ {
+ ArgumentNotNull(edmFunction, "edmFunction");
+
+ var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
+ return returnParamsProperty == null
+ ? edmFunction.ReturnParameter
+ : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
+ }
+
+ public bool IsComposable(EdmFunction edmFunction)
+ {
+ ArgumentNotNull(edmFunction, "edmFunction");
+
+ var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
+ return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
+ }
+
+ public IEnumerable GetParameters(EdmFunction edmFunction)
+ {
+ return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
+ }
+
+ public TypeUsage GetReturnType(EdmFunction edmFunction)
+ {
+ var returnParam = GetReturnParameter(edmFunction);
+ return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
+ }
+
+ public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
+ {
+ var returnType = GetReturnType(edmFunction);
+ return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
+ }
+}
+
+public static void ArgumentNotNull(T arg, string name) where T : class
+{
+ if (arg == null)
+ {
+ throw new ArgumentNullException(name);
+ }
+}
+#>
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.Interface.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.Interface.cs
new file mode 100644
index 0000000..71c2b75
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.Interface.cs
@@ -0,0 +1,12 @@
+using MetallicBlueDev.EntityGate.InterfacedObject;
+
+namespace MetallicBlueDev.Sample.Data
+{
+ public partial class SampleEntity1 : IEntityObjectIdentifier
+ {
+ ///
+ /// Mandatory implementation of the interface.
+ ///
+ public object Identifier => Id;
+ }
+}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.cs
new file mode 100644
index 0000000..64d762e
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.cs
@@ -0,0 +1,17 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated from a template.
+//
+// Manual changes to this file may cause unexpected behavior in your application.
+// Manual changes to this file will be overwritten if the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace MetallicBlueDev.Sample.Data
+{
+ public partial class SampleEntity1
+ {
+ public int Id { get; set; }
+ public int Value { get; set; }
+ }
+}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/App.configsample b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/App.config
similarity index 70%
rename from MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/App.configsample
rename to MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/App.config
index 114f23d..e7769e1 100644
--- a/MetallicBlueDev.EntityGate/MetallicBlueDev.EntityGate/App.configsample
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/App.config
@@ -14,10 +14,32 @@
+
SampleDbInstance
+
+
5
+
+
1000
+
+
30
+
+
+ False
+
+
+ False
+
+
+
+
+
+ DbInstance2
OtherDbInstance
@@ -32,6 +54,7 @@
DbInstance2
1000
+ False
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/BasicSample.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/BasicSample.cs
new file mode 100644
index 0000000..f7515d5
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/BasicSample.cs
@@ -0,0 +1,42 @@
+using MetallicBlueDev.EntityGate;
+using MetallicBlueDev.Sample.Data;
+
+namespace MetallicBlueDev.Sample.EntityGate
+{
+ class BasicSample
+ {
+ public void Test()
+ {
+ // Creation of a new entity.
+ var sample1 = new SampleEntity1();
+ sample1.Value = 3;
+
+ //// EntityGate support and database registration.
+ var gate = new EntityGateObject(sample1);
+
+ if (gate.Save())
+ {
+ // New data saved in database.
+ }
+
+ // Creation of a new entity.
+ gate.NewEntity();
+ gate.Entity.Value = 4;
+ gate.Save();
+
+ // Loading the primary key "10" and obtaining the entity.
+ gate.Load(identifier: 10);
+ sample1 = gate.Entity;
+
+ // Support for another entity.
+ var gate2 = new EntityGateObject();
+
+ // Loading the primary key "33"...
+ if (gate2.Load(33))
+ {
+ // ...and obtaining the entity.
+ OtherEntity sample2 = gate2.Entity;
+ }
+ }
+ }
+}
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/MetallicBlueDev.Sample.EntityGate.csproj b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/MetallicBlueDev.Sample.EntityGate.csproj
new file mode 100644
index 0000000..d2bff59
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/MetallicBlueDev.Sample.EntityGate.csproj
@@ -0,0 +1,66 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {CD267A11-4D5F-4AA9-B411-29E630681909}
+ Library
+ Properties
+ MetallicBlueDev.Sample.EntityGate
+ MetallicBlueDev.Sample.EntityGate
+ v4.7.2
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {1898d29f-7fe8-4c29-a6ff-57860703d4d0}
+ MetallicBlueDev.EntityGate
+
+
+ {52f9655c-6895-4fbc-b3d2-f50ea9cc5356}
+ MetallicBlueDev.Sample.Data
+
+
+
+
+ 6.3.0
+
+
+
+
\ No newline at end of file
diff --git a/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/Properties/AssemblyInfo.cs b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cc725b3
--- /dev/null
+++ b/MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MetallicBlueDev.Sample.EntityGate")]
+[assembly: AssemblyDescription("Sample.EntityGate")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("MetallicBlueDev")]
+[assembly: AssemblyProduct("MetallicBlueDev.Sample.EntityGate")]
+[assembly: AssemblyCopyright("MetallicBlueDev")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("cd267a11-4d5f-4aa9-b411-29e630681909")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/README.md b/README.md
index 7c1c5f0..66618fd 100644
--- a/README.md
+++ b/README.md
@@ -19,35 +19,6 @@ __If one or more scenarios answer your request, this library might interest you.
# Example
-```
-// Creation of a new entity.
-SampleEntity1 sample1 = new SampleEntity1();
-sample1.Value = 3;
-
-// EntityGate support and database registration.
-EntityGateObject<> gate = new EntityGateObject(sample1);
-
-if (gate.Save()) {
- // New data saved in database.
-}
-
-// Creation of a new entity.
-gate.NewEntity();
-gate.Value = 4;
-gate.Save();
-
-// Loading the primary key "10" and obtaining the entity.
-gate.Load(identifier=10);
-sample1 = gate.Entity;
-
-// Support for another entity.
-EntityGateObject<> gate = new EntityGateObject(sample1);
-
-// Loading the primary key "33"...
-if (gate.Load(33)) {
- // ...and obtaining the entity.
- OtherEntity sample2 = gate.Entity;
-}
-```
-
-More example to come.
\ No newline at end of file
+* [Example of a configuration file](MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/App.config)
+* [Example of simple use.](MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.EntityGate/BasicSample.cs)
+* [Example of implementation on entities.](MetallicBlueDev.EntityGate/MetallicBlueDev.Sample.Data/SampleEntity1.Interface.cs)