1
|
<#@ template language="C#" debug="false" hostspecific="true"#>
|
2
|
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
|
3
|
output extension=".cs"#><#
|
4
|
|
5
|
const string inputFile = @"markusModel.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<EntityType>(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<ComplexType>(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
|
// <auto-generated>
|
230
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
|
231
|
//
|
232
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
|
233
|
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
|
234
|
// </auto-generated>
|
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<string, string, string, string> 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<MetadataItem>();
|
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<string> types, string sourceFile)
|
602
|
{
|
603
|
ArgumentNotNull(types, "types");
|
604
|
ArgumentNotNull(sourceFile, "sourceFile");
|
605
|
|
606
|
var hash = new HashSet<string>(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<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
|
618
|
{
|
619
|
return GetItemsToGenerate<SimpleType>(itemCollection)
|
620
|
.Where(e => IsEnumType(e));
|
621
|
}
|
622
|
|
623
|
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
|
624
|
{
|
625
|
return itemCollection
|
626
|
.OfType<T>()
|
627
|
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
|
628
|
.OrderBy(i => i.Name);
|
629
|
}
|
630
|
|
631
|
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> 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<EdmProperty> GetSimpleProperties(EntityType type)
|
651
|
{
|
652
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
|
653
|
}
|
654
|
|
655
|
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
|
656
|
{
|
657
|
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
|
658
|
}
|
659
|
|
660
|
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
|
661
|
{
|
662
|
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
|
663
|
}
|
664
|
|
665
|
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
|
666
|
{
|
667
|
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
|
668
|
}
|
669
|
|
670
|
public IEnumerable<EdmProperty> 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<EdmProperty> 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<NavigationProperty> GetNavigationProperties(EntityType type)
|
681
|
{
|
682
|
return type.NavigationProperties.Where(np => np.DeclaringType == type);
|
683
|
}
|
684
|
|
685
|
public IEnumerable<NavigationProperty> 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<FunctionParameter>)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<FunctionImportParameter> 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>(T arg, string name) where T : class
|
727
|
{
|
728
|
if (arg == null)
|
729
|
{
|
730
|
throw new ArgumentNullException(name);
|
731
|
}
|
732
|
}
|
733
|
#>
|