├── .gitattributes
├── .gitignore
├── EdmxDesignHost
├── EdmxDesignHost.csproj
├── Entities.Context.cs
├── Entities.Context.tt
├── Entities.Designer.cs
├── Entities.cs
├── Entities.edmx
├── Entities.edmx.diagram
├── Entities.tt
├── Person.cs
├── Properties
│ └── AssemblyInfo.cs
└── Thing.cs
├── EdmxDotNetCoreApp.sln
├── EdmxDotNetCoreSample
├── App.Config
├── EdmxDotNetCoreSample.csproj
└── Program.cs
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
--------------------------------------------------------------------------------
/EdmxDesignHost/EdmxDesignHost.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {35174D51-AF4E-42E3-AE51-23ADFA811065}
8 | Library
9 | EF6DotNetCoreApp
10 | EdmxDesignHost
11 | v4.7.2
12 | 512
13 | true
14 | true
15 |
16 |
17 |
18 |
19 | AnyCPU
20 | true
21 | full
22 | false
23 | bin\Debug\
24 | DEBUG;TRACE
25 | prompt
26 | 4
27 |
28 |
29 | AnyCPU
30 | pdbonly
31 | true
32 | bin\Release\
33 | TRACE
34 | prompt
35 | 4
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | True
56 | True
57 | Entities.Context.tt
58 |
59 |
60 | True
61 | True
62 | Entities.tt
63 |
64 |
65 | True
66 | True
67 | Entities.edmx
68 |
69 |
70 | Entities.tt
71 |
72 |
73 |
74 | Entities.tt
75 |
76 |
77 |
78 |
79 | EntityModelCodeGenerator
80 | Entities.Designer.cs
81 |
82 |
83 | Entities.edmx
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | TextTemplatingFileGenerator
92 | Entities.edmx
93 | Entities.Context.cs
94 |
95 |
96 | TextTemplatingFileGenerator
97 | Entities.edmx
98 | Entities.cs
99 |
100 |
101 |
102 |
103 | 6.3.0-preview8-19405-04
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.Context.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace EdmxDotNetCoreSample
11 | {
12 | using System;
13 | using System.Data.Entity;
14 | using System.Data.Entity.Infrastructure;
15 |
16 | public partial class Entities : DbContext
17 | {
18 | public Entities()
19 | : base("name=Entities")
20 | {
21 | }
22 |
23 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
24 | {
25 | throw new UnintentionalCodeFirstException();
26 | }
27 |
28 | public virtual DbSet Things { get; set; }
29 | public virtual DbSet People { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.Context.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" debug="false" hostspecific="true"#>
2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@
3 | output extension=".cs"#><#
4 |
5 | const string inputFile = @"Entities.edmx";
6 | var textTransform = DynamicTextTransformation.Create(this);
7 | var code = new CodeGenerationTools(this);
8 | var ef = new MetadataTools(this);
9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10 | var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
11 | var itemCollection = loader.CreateEdmItemCollection(inputFile);
12 | var modelNamespace = loader.GetModelNamespace(inputFile);
13 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
14 |
15 | var container = itemCollection.OfType().FirstOrDefault();
16 | if (container == null)
17 | {
18 | return string.Empty;
19 | }
20 | #>
21 | //------------------------------------------------------------------------------
22 | //
23 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
24 | //
25 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
26 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
27 | //
28 | //------------------------------------------------------------------------------
29 |
30 | <#
31 |
32 | var codeNamespace = code.VsNamespaceSuggestion();
33 | if (!String.IsNullOrEmpty(codeNamespace))
34 | {
35 | #>
36 | namespace <#=code.EscapeNamespace(codeNamespace)#>
37 | {
38 | <#
39 | PushIndent(" ");
40 | }
41 |
42 | #>
43 | using System;
44 | using System.Data.Entity;
45 | using System.Data.Entity.Infrastructure;
46 | <#
47 | if (container.FunctionImports.Any())
48 | {
49 | #>
50 | using System.Data.Entity.Core.Objects;
51 | using System.Linq;
52 | <#
53 | }
54 | #>
55 |
56 | <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
57 | {
58 | public <#=code.Escape(container)#>()
59 | : base("name=<#=container.Name#>")
60 | {
61 | <#
62 | if (!loader.IsLazyLoadingEnabled(container))
63 | {
64 | #>
65 | this.Configuration.LazyLoadingEnabled = false;
66 | <#
67 | }
68 |
69 | foreach (var entitySet in container.BaseEntitySets.OfType())
70 | {
71 | // Note: the DbSet members are defined below such that the getter and
72 | // setter always have the same accessibility as the DbSet definition
73 | if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
74 | {
75 | #>
76 | <#=codeStringGenerator.DbSetInitializer(entitySet)#>
77 | <#
78 | }
79 | }
80 | #>
81 | }
82 |
83 | protected override void OnModelCreating(DbModelBuilder modelBuilder)
84 | {
85 | throw new UnintentionalCodeFirstException();
86 | }
87 |
88 | <#
89 | foreach (var entitySet in container.BaseEntitySets.OfType())
90 | {
91 | #>
92 | <#=codeStringGenerator.DbSet(entitySet)#>
93 | <#
94 | }
95 |
96 | foreach (var edmFunction in container.FunctionImports)
97 | {
98 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
99 | }
100 | #>
101 | }
102 | <#
103 |
104 | if (!String.IsNullOrEmpty(codeNamespace))
105 | {
106 | PopIndent();
107 | #>
108 | }
109 | <#
110 | }
111 | #>
112 | <#+
113 |
114 | private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
115 | {
116 | if (typeMapper.IsComposable(edmFunction))
117 | {
118 | #>
119 |
120 | [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
121 | <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
122 | {
123 | <#+
124 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
125 | #>
126 | <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
127 | }
128 | <#+
129 | }
130 | else
131 | {
132 | #>
133 |
134 | <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
135 | {
136 | <#+
137 | codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
138 | #>
139 | <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
140 | }
141 | <#+
142 | if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
143 | {
144 | WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
145 | }
146 | }
147 | }
148 |
149 | public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
150 | {
151 | #>
152 | var <#=name#> = <#=isNotNull#> ?
153 | <#=notNullInit#> :
154 | <#=nullInit#>;
155 |
156 | <#+
157 | }
158 |
159 | public const string TemplateId = "CSharp_DbContext_Context_EF6";
160 |
161 | public class CodeStringGenerator
162 | {
163 | private readonly CodeGenerationTools _code;
164 | private readonly TypeMapper _typeMapper;
165 | private readonly MetadataTools _ef;
166 |
167 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
168 | {
169 | ArgumentNotNull(code, "code");
170 | ArgumentNotNull(typeMapper, "typeMapper");
171 | ArgumentNotNull(ef, "ef");
172 |
173 | _code = code;
174 | _typeMapper = typeMapper;
175 | _ef = ef;
176 | }
177 |
178 | public string Property(EdmProperty edmProperty)
179 | {
180 | return string.Format(
181 | CultureInfo.InvariantCulture,
182 | "{0} {1} {2} {{ {3}get; {4}set; }}",
183 | Accessibility.ForProperty(edmProperty),
184 | _typeMapper.GetTypeName(edmProperty.TypeUsage),
185 | _code.Escape(edmProperty),
186 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
187 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
188 | }
189 |
190 | public string NavigationProperty(NavigationProperty navProp)
191 | {
192 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
193 | return string.Format(
194 | CultureInfo.InvariantCulture,
195 | "{0} {1} {2} {{ {3}get; {4}set; }}",
196 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
197 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
198 | _code.Escape(navProp),
199 | _code.SpaceAfter(Accessibility.ForGetter(navProp)),
200 | _code.SpaceAfter(Accessibility.ForSetter(navProp)));
201 | }
202 |
203 | public string AccessibilityAndVirtual(string accessibility)
204 | {
205 | return accessibility + (accessibility != "private" ? " virtual" : "");
206 | }
207 |
208 | public string EntityClassOpening(EntityType entity)
209 | {
210 | return string.Format(
211 | CultureInfo.InvariantCulture,
212 | "{0} {1}partial class {2}{3}",
213 | Accessibility.ForType(entity),
214 | _code.SpaceAfter(_code.AbstractOption(entity)),
215 | _code.Escape(entity),
216 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
217 | }
218 |
219 | public string EnumOpening(SimpleType enumType)
220 | {
221 | return string.Format(
222 | CultureInfo.InvariantCulture,
223 | "{0} enum {1} : {2}",
224 | Accessibility.ForType(enumType),
225 | _code.Escape(enumType),
226 | _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
227 | }
228 |
229 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
230 | {
231 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
232 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
233 | {
234 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
235 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
236 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
237 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
238 | }
239 | }
240 |
241 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
242 | {
243 | var parameters = _typeMapper.GetParameters(edmFunction);
244 |
245 | return string.Format(
246 | CultureInfo.InvariantCulture,
247 | "{0} IQueryable<{1}> {2}({3})",
248 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
249 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
250 | _code.Escape(edmFunction),
251 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
252 | }
253 |
254 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
255 | {
256 | var parameters = _typeMapper.GetParameters(edmFunction);
257 |
258 | return string.Format(
259 | CultureInfo.InvariantCulture,
260 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
261 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
262 | edmFunction.NamespaceName,
263 | edmFunction.Name,
264 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
265 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
266 | }
267 |
268 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
269 | {
270 | var parameters = _typeMapper.GetParameters(edmFunction);
271 | var returnType = _typeMapper.GetReturnType(edmFunction);
272 |
273 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
274 | if (includeMergeOption)
275 | {
276 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
277 | }
278 |
279 | return string.Format(
280 | CultureInfo.InvariantCulture,
281 | "{0} {1} {2}({3})",
282 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
283 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
284 | _code.Escape(edmFunction),
285 | paramList);
286 | }
287 |
288 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
289 | {
290 | var parameters = _typeMapper.GetParameters(edmFunction);
291 | var returnType = _typeMapper.GetReturnType(edmFunction);
292 |
293 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
294 | if (includeMergeOption)
295 | {
296 | callParams = ", mergeOption" + callParams;
297 | }
298 |
299 | return string.Format(
300 | CultureInfo.InvariantCulture,
301 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
302 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
303 | edmFunction.Name,
304 | callParams);
305 | }
306 |
307 | public string DbSet(EntitySet entitySet)
308 | {
309 | return string.Format(
310 | CultureInfo.InvariantCulture,
311 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
312 | Accessibility.ForReadOnlyProperty(entitySet),
313 | _typeMapper.GetTypeName(entitySet.ElementType),
314 | _code.Escape(entitySet));
315 | }
316 |
317 | public string DbSetInitializer(EntitySet entitySet)
318 | {
319 | return string.Format(
320 | CultureInfo.InvariantCulture,
321 | "{0} = Set<{1}>();",
322 | _code.Escape(entitySet),
323 | _typeMapper.GetTypeName(entitySet.ElementType));
324 | }
325 |
326 | public string UsingDirectives(bool inHeader, bool includeCollections = true)
327 | {
328 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
329 | ? string.Format(
330 | CultureInfo.InvariantCulture,
331 | "{0}using System;{1}" +
332 | "{2}",
333 | inHeader ? Environment.NewLine : "",
334 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
335 | inHeader ? "" : Environment.NewLine)
336 | : "";
337 | }
338 | }
339 |
340 | public class TypeMapper
341 | {
342 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
343 |
344 | private readonly System.Collections.IList _errors;
345 | private readonly CodeGenerationTools _code;
346 | private readonly MetadataTools _ef;
347 |
348 | public static string FixNamespaces(string typeName)
349 | {
350 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
351 | }
352 |
353 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
354 | {
355 | ArgumentNotNull(code, "code");
356 | ArgumentNotNull(ef, "ef");
357 | ArgumentNotNull(errors, "errors");
358 |
359 | _code = code;
360 | _ef = ef;
361 | _errors = errors;
362 | }
363 |
364 | public string GetTypeName(TypeUsage typeUsage)
365 | {
366 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
367 | }
368 |
369 | public string GetTypeName(EdmType edmType)
370 | {
371 | return GetTypeName(edmType, isNullable: null, modelNamespace: null);
372 | }
373 |
374 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
375 | {
376 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
377 | }
378 |
379 | public string GetTypeName(EdmType edmType, string modelNamespace)
380 | {
381 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
382 | }
383 |
384 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
385 | {
386 | if (edmType == null)
387 | {
388 | return null;
389 | }
390 |
391 | var collectionType = edmType as CollectionType;
392 | if (collectionType != null)
393 | {
394 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
395 | }
396 |
397 | var typeName = _code.Escape(edmType.MetadataProperties
398 | .Where(p => p.Name == ExternalTypeNameAttributeName)
399 | .Select(p => (string)p.Value)
400 | .FirstOrDefault())
401 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
402 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
403 | _code.Escape(edmType));
404 |
405 | if (edmType is StructuralType)
406 | {
407 | return typeName;
408 | }
409 |
410 | if (edmType is SimpleType)
411 | {
412 | var clrType = UnderlyingClrType(edmType);
413 | if (!IsEnumType(edmType))
414 | {
415 | typeName = _code.Escape(clrType);
416 | }
417 |
418 | typeName = FixNamespaces(typeName);
419 |
420 | return clrType.IsValueType && isNullable == true ?
421 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
422 | typeName;
423 | }
424 |
425 | throw new ArgumentException("edmType");
426 | }
427 |
428 | public Type UnderlyingClrType(EdmType edmType)
429 | {
430 | ArgumentNotNull(edmType, "edmType");
431 |
432 | var primitiveType = edmType as PrimitiveType;
433 | if (primitiveType != null)
434 | {
435 | return primitiveType.ClrEquivalentType;
436 | }
437 |
438 | if (IsEnumType(edmType))
439 | {
440 | return GetEnumUnderlyingType(edmType).ClrEquivalentType;
441 | }
442 |
443 | return typeof(object);
444 | }
445 |
446 | public object GetEnumMemberValue(MetadataItem enumMember)
447 | {
448 | ArgumentNotNull(enumMember, "enumMember");
449 |
450 | var valueProperty = enumMember.GetType().GetProperty("Value");
451 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
452 | }
453 |
454 | public string GetEnumMemberName(MetadataItem enumMember)
455 | {
456 | ArgumentNotNull(enumMember, "enumMember");
457 |
458 | var nameProperty = enumMember.GetType().GetProperty("Name");
459 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
460 | }
461 |
462 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
463 | {
464 | ArgumentNotNull(enumType, "enumType");
465 |
466 | var membersProperty = enumType.GetType().GetProperty("Members");
467 | return membersProperty != null
468 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
469 | : Enumerable.Empty();
470 | }
471 |
472 | public bool EnumIsFlags(EdmType enumType)
473 | {
474 | ArgumentNotNull(enumType, "enumType");
475 |
476 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
477 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
478 | }
479 |
480 | public bool IsEnumType(GlobalItem edmType)
481 | {
482 | ArgumentNotNull(edmType, "edmType");
483 |
484 | return edmType.GetType().Name == "EnumType";
485 | }
486 |
487 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
488 | {
489 | ArgumentNotNull(enumType, "enumType");
490 |
491 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
492 | }
493 |
494 | public string CreateLiteral(object value)
495 | {
496 | if (value == null || value.GetType() != typeof(TimeSpan))
497 | {
498 | return _code.CreateLiteral(value);
499 | }
500 |
501 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
502 | }
503 |
504 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
505 | {
506 | ArgumentNotNull(types, "types");
507 | ArgumentNotNull(sourceFile, "sourceFile");
508 |
509 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
510 | if (types.Any(item => !hash.Add(item)))
511 | {
512 | _errors.Add(
513 | new CompilerError(sourceFile, -1, -1, "6023",
514 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
515 | return false;
516 | }
517 | return true;
518 | }
519 |
520 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
521 | {
522 | return GetItemsToGenerate(itemCollection)
523 | .Where(e => IsEnumType(e));
524 | }
525 |
526 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
527 | {
528 | return itemCollection
529 | .OfType()
530 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
531 | .OrderBy(i => i.Name);
532 | }
533 |
534 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
535 | {
536 | return itemCollection
537 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
538 | .Select(g => GetGlobalItemName(g));
539 | }
540 |
541 | public string GetGlobalItemName(GlobalItem item)
542 | {
543 | if (item is EdmType)
544 | {
545 | return ((EdmType)item).Name;
546 | }
547 | else
548 | {
549 | return ((EntityContainer)item).Name;
550 | }
551 | }
552 |
553 | public IEnumerable GetSimpleProperties(EntityType type)
554 | {
555 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
556 | }
557 |
558 | public IEnumerable GetSimpleProperties(ComplexType type)
559 | {
560 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
561 | }
562 |
563 | public IEnumerable GetComplexProperties(EntityType type)
564 | {
565 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
566 | }
567 |
568 | public IEnumerable GetComplexProperties(ComplexType type)
569 | {
570 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
571 | }
572 |
573 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
574 | {
575 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
576 | }
577 |
578 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
579 | {
580 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
581 | }
582 |
583 | public IEnumerable GetNavigationProperties(EntityType type)
584 | {
585 | return type.NavigationProperties.Where(np => np.DeclaringType == type);
586 | }
587 |
588 | public IEnumerable GetCollectionNavigationProperties(EntityType type)
589 | {
590 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
591 | }
592 |
593 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
594 | {
595 | ArgumentNotNull(edmFunction, "edmFunction");
596 |
597 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
598 | return returnParamsProperty == null
599 | ? edmFunction.ReturnParameter
600 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
601 | }
602 |
603 | public bool IsComposable(EdmFunction edmFunction)
604 | {
605 | ArgumentNotNull(edmFunction, "edmFunction");
606 |
607 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
608 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
609 | }
610 |
611 | public IEnumerable GetParameters(EdmFunction edmFunction)
612 | {
613 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
614 | }
615 |
616 | public TypeUsage GetReturnType(EdmFunction edmFunction)
617 | {
618 | var returnParam = GetReturnParameter(edmFunction);
619 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
620 | }
621 |
622 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
623 | {
624 | var returnType = GetReturnType(edmFunction);
625 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
626 | }
627 | }
628 |
629 | public static void ArgumentNotNull(T arg, string name) where T : class
630 | {
631 | if (arg == null)
632 | {
633 | throw new ArgumentNullException(name);
634 | }
635 | }
636 | #>
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.Designer.cs:
--------------------------------------------------------------------------------
1 | // T4 code generation is enabled for model 'C:\Users\divega\source\repos\EdmxDesignHost\Entities.edmx'.
2 | // To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
3 | // property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
4 | // is open in the designer.
5 |
6 | // If no context and entity classes have been generated, it may be because you created an empty model but
7 | // have not yet chosen which version of Entity Framework to use. To generate a context class and entity
8 | // classes for your model, open the model in the designer, right-click on the designer surface, and
9 | // select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
10 | // Item...'.
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.edmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.edmx.diagram:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Entities.tt:
--------------------------------------------------------------------------------
1 | <#@ template language="C#" debug="false" hostspecific="true"#>
2 | <#@ include file="EF6.Utility.CS.ttinclude"#><#@
3 | output extension=".cs"#><#
4 |
5 | const string inputFile = @"Entities.edmx";
6 | var textTransform = DynamicTextTransformation.Create(this);
7 | var code = new CodeGenerationTools(this);
8 | var ef = new MetadataTools(this);
9 | var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
10 | var fileManager = EntityFrameworkTemplateFileManager.Create(this);
11 | var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
12 | var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
13 |
14 | if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
15 | {
16 | return string.Empty;
17 | }
18 |
19 | WriteHeader(codeStringGenerator, fileManager);
20 |
21 | foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection))
22 | {
23 | fileManager.StartNewFile(entity.Name + ".cs");
24 | BeginNamespace(code);
25 | #>
26 | <#=codeStringGenerator.UsingDirectives(inHeader: false)#>
27 | <#=codeStringGenerator.EntityClassOpening(entity)#>
28 | {
29 | <#
30 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
31 | var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
32 | var complexProperties = typeMapper.GetComplexProperties(entity);
33 |
34 | if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
35 | {
36 | #>
37 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
38 | public <#=code.Escape(entity)#>()
39 | {
40 | <#
41 | foreach (var edmProperty in propertiesWithDefaultValues)
42 | {
43 | #>
44 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
45 | <#
46 | }
47 |
48 | foreach (var navigationProperty in collectionNavigationProperties)
49 | {
50 | #>
51 | this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
52 | <#
53 | }
54 |
55 | foreach (var complexProperty in complexProperties)
56 | {
57 | #>
58 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
59 | <#
60 | }
61 | #>
62 | }
63 |
64 | <#
65 | }
66 |
67 | var simpleProperties = typeMapper.GetSimpleProperties(entity);
68 | if (simpleProperties.Any())
69 | {
70 | foreach (var edmProperty in simpleProperties)
71 | {
72 | #>
73 | <#=codeStringGenerator.Property(edmProperty)#>
74 | <#
75 | }
76 | }
77 |
78 | if (complexProperties.Any())
79 | {
80 | #>
81 |
82 | <#
83 | foreach(var complexProperty in complexProperties)
84 | {
85 | #>
86 | <#=codeStringGenerator.Property(complexProperty)#>
87 | <#
88 | }
89 | }
90 |
91 | var navigationProperties = typeMapper.GetNavigationProperties(entity);
92 | if (navigationProperties.Any())
93 | {
94 | #>
95 |
96 | <#
97 | foreach (var navigationProperty in navigationProperties)
98 | {
99 | if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
100 | {
101 | #>
102 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
103 | <#
104 | }
105 | #>
106 | <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
107 | <#
108 | }
109 | }
110 | #>
111 | }
112 | <#
113 | EndNamespace(code);
114 | }
115 |
116 | foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection))
117 | {
118 | fileManager.StartNewFile(complex.Name + ".cs");
119 | BeginNamespace(code);
120 | #>
121 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
122 | <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
123 | {
124 | <#
125 | var complexProperties = typeMapper.GetComplexProperties(complex);
126 | var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
127 |
128 | if (propertiesWithDefaultValues.Any() || complexProperties.Any())
129 | {
130 | #>
131 | public <#=code.Escape(complex)#>()
132 | {
133 | <#
134 | foreach (var edmProperty in propertiesWithDefaultValues)
135 | {
136 | #>
137 | this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
138 | <#
139 | }
140 |
141 | foreach (var complexProperty in complexProperties)
142 | {
143 | #>
144 | this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
145 | <#
146 | }
147 | #>
148 | }
149 |
150 | <#
151 | }
152 |
153 | var simpleProperties = typeMapper.GetSimpleProperties(complex);
154 | if (simpleProperties.Any())
155 | {
156 | foreach(var edmProperty in simpleProperties)
157 | {
158 | #>
159 | <#=codeStringGenerator.Property(edmProperty)#>
160 | <#
161 | }
162 | }
163 |
164 | if (complexProperties.Any())
165 | {
166 | #>
167 |
168 | <#
169 | foreach(var edmProperty in complexProperties)
170 | {
171 | #>
172 | <#=codeStringGenerator.Property(edmProperty)#>
173 | <#
174 | }
175 | }
176 | #>
177 | }
178 | <#
179 | EndNamespace(code);
180 | }
181 |
182 | foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
183 | {
184 | fileManager.StartNewFile(enumType.Name + ".cs");
185 | BeginNamespace(code);
186 | #>
187 | <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
188 | <#
189 | if (typeMapper.EnumIsFlags(enumType))
190 | {
191 | #>
192 | [Flags]
193 | <#
194 | }
195 | #>
196 | <#=codeStringGenerator.EnumOpening(enumType)#>
197 | {
198 | <#
199 | var foundOne = false;
200 |
201 | foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
202 | {
203 | foundOne = true;
204 | #>
205 | <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
206 | <#
207 | }
208 |
209 | if (foundOne)
210 | {
211 | this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
212 | }
213 | #>
214 | }
215 | <#
216 | EndNamespace(code);
217 | }
218 |
219 | fileManager.Process();
220 |
221 | #>
222 | <#+
223 |
224 | public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
225 | {
226 | fileManager.StartHeader();
227 | #>
228 | //------------------------------------------------------------------------------
229 | //
230 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
231 | //
232 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
233 | // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
234 | //
235 | //------------------------------------------------------------------------------
236 | <#=codeStringGenerator.UsingDirectives(inHeader: true)#>
237 | <#+
238 | fileManager.EndBlock();
239 | }
240 |
241 | public void BeginNamespace(CodeGenerationTools code)
242 | {
243 | var codeNamespace = code.VsNamespaceSuggestion();
244 | if (!String.IsNullOrEmpty(codeNamespace))
245 | {
246 | #>
247 | namespace <#=code.EscapeNamespace(codeNamespace)#>
248 | {
249 | <#+
250 | PushIndent(" ");
251 | }
252 | }
253 |
254 | public void EndNamespace(CodeGenerationTools code)
255 | {
256 | if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
257 | {
258 | PopIndent();
259 | #>
260 | }
261 | <#+
262 | }
263 | }
264 |
265 | public const string TemplateId = "CSharp_DbContext_Types_EF6";
266 |
267 | public class CodeStringGenerator
268 | {
269 | private readonly CodeGenerationTools _code;
270 | private readonly TypeMapper _typeMapper;
271 | private readonly MetadataTools _ef;
272 |
273 | public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
274 | {
275 | ArgumentNotNull(code, "code");
276 | ArgumentNotNull(typeMapper, "typeMapper");
277 | ArgumentNotNull(ef, "ef");
278 |
279 | _code = code;
280 | _typeMapper = typeMapper;
281 | _ef = ef;
282 | }
283 |
284 | public string Property(EdmProperty edmProperty)
285 | {
286 | return string.Format(
287 | CultureInfo.InvariantCulture,
288 | "{0} {1} {2} {{ {3}get; {4}set; }}",
289 | Accessibility.ForProperty(edmProperty),
290 | _typeMapper.GetTypeName(edmProperty.TypeUsage),
291 | _code.Escape(edmProperty),
292 | _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
293 | _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
294 | }
295 |
296 | public string NavigationProperty(NavigationProperty navProp)
297 | {
298 | var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
299 | return string.Format(
300 | CultureInfo.InvariantCulture,
301 | "{0} {1} {2} {{ {3}get; {4}set; }}",
302 | AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
303 | navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
304 | _code.Escape(navProp),
305 | _code.SpaceAfter(Accessibility.ForGetter(navProp)),
306 | _code.SpaceAfter(Accessibility.ForSetter(navProp)));
307 | }
308 |
309 | public string AccessibilityAndVirtual(string accessibility)
310 | {
311 | return accessibility + (accessibility != "private" ? " virtual" : "");
312 | }
313 |
314 | public string EntityClassOpening(EntityType entity)
315 | {
316 | return string.Format(
317 | CultureInfo.InvariantCulture,
318 | "{0} {1}partial class {2}{3}",
319 | Accessibility.ForType(entity),
320 | _code.SpaceAfter(_code.AbstractOption(entity)),
321 | _code.Escape(entity),
322 | _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
323 | }
324 |
325 | public string EnumOpening(SimpleType enumType)
326 | {
327 | return string.Format(
328 | CultureInfo.InvariantCulture,
329 | "{0} enum {1} : {2}",
330 | Accessibility.ForType(enumType),
331 | _code.Escape(enumType),
332 | _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
333 | }
334 |
335 | public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
336 | {
337 | var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
338 | foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
339 | {
340 | var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
341 | var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
342 | var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
343 | writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
344 | }
345 | }
346 |
347 | public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
348 | {
349 | var parameters = _typeMapper.GetParameters(edmFunction);
350 |
351 | return string.Format(
352 | CultureInfo.InvariantCulture,
353 | "{0} IQueryable<{1}> {2}({3})",
354 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
355 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
356 | _code.Escape(edmFunction),
357 | string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
358 | }
359 |
360 | public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
361 | {
362 | var parameters = _typeMapper.GetParameters(edmFunction);
363 |
364 | return string.Format(
365 | CultureInfo.InvariantCulture,
366 | "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
367 | _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
368 | edmFunction.NamespaceName,
369 | edmFunction.Name,
370 | string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
371 | _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
372 | }
373 |
374 | public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
375 | {
376 | var parameters = _typeMapper.GetParameters(edmFunction);
377 | var returnType = _typeMapper.GetReturnType(edmFunction);
378 |
379 | var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
380 | if (includeMergeOption)
381 | {
382 | paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
383 | }
384 |
385 | return string.Format(
386 | CultureInfo.InvariantCulture,
387 | "{0} {1} {2}({3})",
388 | AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
389 | returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
390 | _code.Escape(edmFunction),
391 | paramList);
392 | }
393 |
394 | public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
395 | {
396 | var parameters = _typeMapper.GetParameters(edmFunction);
397 | var returnType = _typeMapper.GetReturnType(edmFunction);
398 |
399 | var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
400 | if (includeMergeOption)
401 | {
402 | callParams = ", mergeOption" + callParams;
403 | }
404 |
405 | return string.Format(
406 | CultureInfo.InvariantCulture,
407 | "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
408 | returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
409 | edmFunction.Name,
410 | callParams);
411 | }
412 |
413 | public string DbSet(EntitySet entitySet)
414 | {
415 | return string.Format(
416 | CultureInfo.InvariantCulture,
417 | "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
418 | Accessibility.ForReadOnlyProperty(entitySet),
419 | _typeMapper.GetTypeName(entitySet.ElementType),
420 | _code.Escape(entitySet));
421 | }
422 |
423 | public string UsingDirectives(bool inHeader, bool includeCollections = true)
424 | {
425 | return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
426 | ? string.Format(
427 | CultureInfo.InvariantCulture,
428 | "{0}using System;{1}" +
429 | "{2}",
430 | inHeader ? Environment.NewLine : "",
431 | includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
432 | inHeader ? "" : Environment.NewLine)
433 | : "";
434 | }
435 | }
436 |
437 | public class TypeMapper
438 | {
439 | private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
440 |
441 | private readonly System.Collections.IList _errors;
442 | private readonly CodeGenerationTools _code;
443 | private readonly MetadataTools _ef;
444 |
445 | public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
446 | {
447 | ArgumentNotNull(code, "code");
448 | ArgumentNotNull(ef, "ef");
449 | ArgumentNotNull(errors, "errors");
450 |
451 | _code = code;
452 | _ef = ef;
453 | _errors = errors;
454 | }
455 |
456 | public static string FixNamespaces(string typeName)
457 | {
458 | return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
459 | }
460 |
461 | public string GetTypeName(TypeUsage typeUsage)
462 | {
463 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
464 | }
465 |
466 | public string GetTypeName(EdmType edmType)
467 | {
468 | return GetTypeName(edmType, isNullable: null, modelNamespace: null);
469 | }
470 |
471 | public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
472 | {
473 | return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
474 | }
475 |
476 | public string GetTypeName(EdmType edmType, string modelNamespace)
477 | {
478 | return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
479 | }
480 |
481 | public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
482 | {
483 | if (edmType == null)
484 | {
485 | return null;
486 | }
487 |
488 | var collectionType = edmType as CollectionType;
489 | if (collectionType != null)
490 | {
491 | return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
492 | }
493 |
494 | var typeName = _code.Escape(edmType.MetadataProperties
495 | .Where(p => p.Name == ExternalTypeNameAttributeName)
496 | .Select(p => (string)p.Value)
497 | .FirstOrDefault())
498 | ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
499 | _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
500 | _code.Escape(edmType));
501 |
502 | if (edmType is StructuralType)
503 | {
504 | return typeName;
505 | }
506 |
507 | if (edmType is SimpleType)
508 | {
509 | var clrType = UnderlyingClrType(edmType);
510 | if (!IsEnumType(edmType))
511 | {
512 | typeName = _code.Escape(clrType);
513 | }
514 |
515 | typeName = FixNamespaces(typeName);
516 |
517 | return clrType.IsValueType && isNullable == true ?
518 | String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
519 | typeName;
520 | }
521 |
522 | throw new ArgumentException("edmType");
523 | }
524 |
525 | public Type UnderlyingClrType(EdmType edmType)
526 | {
527 | ArgumentNotNull(edmType, "edmType");
528 |
529 | var primitiveType = edmType as PrimitiveType;
530 | if (primitiveType != null)
531 | {
532 | return primitiveType.ClrEquivalentType;
533 | }
534 |
535 | if (IsEnumType(edmType))
536 | {
537 | return GetEnumUnderlyingType(edmType).ClrEquivalentType;
538 | }
539 |
540 | return typeof(object);
541 | }
542 |
543 | public object GetEnumMemberValue(MetadataItem enumMember)
544 | {
545 | ArgumentNotNull(enumMember, "enumMember");
546 |
547 | var valueProperty = enumMember.GetType().GetProperty("Value");
548 | return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
549 | }
550 |
551 | public string GetEnumMemberName(MetadataItem enumMember)
552 | {
553 | ArgumentNotNull(enumMember, "enumMember");
554 |
555 | var nameProperty = enumMember.GetType().GetProperty("Name");
556 | return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
557 | }
558 |
559 | public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
560 | {
561 | ArgumentNotNull(enumType, "enumType");
562 |
563 | var membersProperty = enumType.GetType().GetProperty("Members");
564 | return membersProperty != null
565 | ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
566 | : Enumerable.Empty();
567 | }
568 |
569 | public bool EnumIsFlags(EdmType enumType)
570 | {
571 | ArgumentNotNull(enumType, "enumType");
572 |
573 | var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
574 | return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
575 | }
576 |
577 | public bool IsEnumType(GlobalItem edmType)
578 | {
579 | ArgumentNotNull(edmType, "edmType");
580 |
581 | return edmType.GetType().Name == "EnumType";
582 | }
583 |
584 | public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
585 | {
586 | ArgumentNotNull(enumType, "enumType");
587 |
588 | return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
589 | }
590 |
591 | public string CreateLiteral(object value)
592 | {
593 | if (value == null || value.GetType() != typeof(TimeSpan))
594 | {
595 | return _code.CreateLiteral(value);
596 | }
597 |
598 | return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
599 | }
600 |
601 | public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
602 | {
603 | ArgumentNotNull(types, "types");
604 | ArgumentNotNull(sourceFile, "sourceFile");
605 |
606 | var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
607 | if (types.Any(item => !hash.Add(item)))
608 | {
609 | _errors.Add(
610 | new CompilerError(sourceFile, -1, -1, "6023",
611 | String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
612 | return false;
613 | }
614 | return true;
615 | }
616 |
617 | public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
618 | {
619 | return GetItemsToGenerate(itemCollection)
620 | .Where(e => IsEnumType(e));
621 | }
622 |
623 | public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
624 | {
625 | return itemCollection
626 | .OfType()
627 | .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
628 | .OrderBy(i => i.Name);
629 | }
630 |
631 | public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
632 | {
633 | return itemCollection
634 | .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
635 | .Select(g => GetGlobalItemName(g));
636 | }
637 |
638 | public string GetGlobalItemName(GlobalItem item)
639 | {
640 | if (item is EdmType)
641 | {
642 | return ((EdmType)item).Name;
643 | }
644 | else
645 | {
646 | return ((EntityContainer)item).Name;
647 | }
648 | }
649 |
650 | public IEnumerable GetSimpleProperties(EntityType type)
651 | {
652 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
653 | }
654 |
655 | public IEnumerable GetSimpleProperties(ComplexType type)
656 | {
657 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
658 | }
659 |
660 | public IEnumerable GetComplexProperties(EntityType type)
661 | {
662 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
663 | }
664 |
665 | public IEnumerable GetComplexProperties(ComplexType type)
666 | {
667 | return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
668 | }
669 |
670 | public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
671 | {
672 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
673 | }
674 |
675 | public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
676 | {
677 | return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
678 | }
679 |
680 | public IEnumerable GetNavigationProperties(EntityType type)
681 | {
682 | return type.NavigationProperties.Where(np => np.DeclaringType == type);
683 | }
684 |
685 | public IEnumerable GetCollectionNavigationProperties(EntityType type)
686 | {
687 | return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
688 | }
689 |
690 | public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
691 | {
692 | ArgumentNotNull(edmFunction, "edmFunction");
693 |
694 | var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
695 | return returnParamsProperty == null
696 | ? edmFunction.ReturnParameter
697 | : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
698 | }
699 |
700 | public bool IsComposable(EdmFunction edmFunction)
701 | {
702 | ArgumentNotNull(edmFunction, "edmFunction");
703 |
704 | var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
705 | return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
706 | }
707 |
708 | public IEnumerable GetParameters(EdmFunction edmFunction)
709 | {
710 | return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
711 | }
712 |
713 | public TypeUsage GetReturnType(EdmFunction edmFunction)
714 | {
715 | var returnParam = GetReturnParameter(edmFunction);
716 | return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
717 | }
718 |
719 | public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
720 | {
721 | var returnType = GetReturnType(edmFunction);
722 | return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
723 | }
724 | }
725 |
726 | public static void ArgumentNotNull(T arg, string name) where T : class
727 | {
728 | if (arg == null)
729 | {
730 | throw new ArgumentNullException(name);
731 | }
732 | }
733 | #>
--------------------------------------------------------------------------------
/EdmxDesignHost/Person.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace EdmxDotNetCoreSample
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Person
16 | {
17 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
18 | public Person()
19 | {
20 | this.Things = new HashSet();
21 | }
22 |
23 | public string Name { get; set; }
24 |
25 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
26 | public virtual ICollection Things { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("EdmxDesignHost")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("EdmxDesignHost")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("35174d51-af4e-42e3-ae51-23adfa811065")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/EdmxDesignHost/Thing.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated from a template.
4 | //
5 | // Manual changes to this file may cause unexpected behavior in your application.
6 | // Manual changes to this file will be overwritten if the code is regenerated.
7 | //
8 | //------------------------------------------------------------------------------
9 |
10 | namespace EdmxDotNetCoreSample
11 | {
12 | using System;
13 | using System.Collections.Generic;
14 |
15 | public partial class Thing
16 | {
17 | public string Name { get; set; }
18 | public string OwnerName { get; set; }
19 |
20 | public virtual Person Owner { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/EdmxDotNetCoreApp.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29218.8
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EdmxDesignHost", "EdmxDesignHost\EdmxDesignHost.csproj", "{35174D51-AF4E-42E3-AE51-23ADFA811065}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EdmxDotNetCoreSample", "EdmxDotNetCoreSample\EdmxDotNetCoreSample.csproj", "{60CFCF24-E2D8-4C68-90EF-DE205FC1659F}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {35174D51-AF4E-42E3-AE51-23ADFA811065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {35174D51-AF4E-42E3-AE51-23ADFA811065}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {35174D51-AF4E-42E3-AE51-23ADFA811065}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {35174D51-AF4E-42E3-AE51-23ADFA811065}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {60CFCF24-E2D8-4C68-90EF-DE205FC1659F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {60CFCF24-E2D8-4C68-90EF-DE205FC1659F}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {60CFCF24-E2D8-4C68-90EF-DE205FC1659F}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {60CFCF24-E2D8-4C68-90EF-DE205FC1659F}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {0EAAC430-C841-440E-AE5F-E77468E47353}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/EdmxDotNetCoreSample/App.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/EdmxDotNetCoreSample/EdmxDotNetCoreSample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp3.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/EdmxDotNetCoreSample/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Data.Entity;
3 | using System.Data.Entity.Infrastructure;
4 | using System.Linq;
5 | using System.Xml;
6 |
7 | namespace EdmxDotNetCoreSample
8 | {
9 | class Program
10 | {
11 | static void Main(string[] args)
12 | {
13 | using (var db = new Entities())
14 | {
15 | db.Database.CreateIfNotExists();
16 | Console.WriteLine(db.People.Include(p=>p.Things).Count());
17 | }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Edmx .NET Core Sample
2 | This sample shows a way to work with edmx (EF6 metadata) in a .NET Core project in Visual Studio without designer support.
3 |
4 | It uses a .NET Framework project to host the edmx file, which is supported by the designer, and then imports the edmx file and the relevant generated entity and DbContext classes as linked files in the .NET Core project.
5 |
6 | That way you can use the designer to visualize and modify the model using the designer, getting any changes automatically impact the generated code using the regular T4 templates, and then use the results from a .NET Core application.
7 |
8 | You will need to add new linked files for any new entity classes you add or rename in the designer.
9 |
--------------------------------------------------------------------------------