| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- <#
- // Simplifying assumptions based on reverse engineer rules
- // - No complex types
- // - One entity container
- // - No inheritance
- // - Always have two navigation properties
- // - All associations expose FKs (except many:many)
- #>
- <#@ template hostspecific="true" language="C#" #>
- <#@ include file="EF.Utility.CS.ttinclude" #><#@
- output extension=".cs" #><#
- var efHost = (EfTextTemplateHost)Host;
- var code = new CodeGenerationTools(this);
- if (efHost.EntityFrameworkVersion >= new Version(4, 4))
- {
- #>
- using System.ComponentModel.DataAnnotations.Schema;
- <#
- }
- else
- {
- #>
- using System.ComponentModel.DataAnnotations;
- <#
- }
- #>
- using System.Data.Entity.ModelConfiguration;
- namespace <#= code.EscapeNamespace(efHost.Namespace) #>
- {
- public class <#= efHost.EntityType.Name #>Map : EntityTypeConfiguration<<#= efHost.EntityType.Name #>>
- {
- public <#= efHost.EntityType.Name #>Map()
- {
- // Primary Key
- <#
- if (efHost.EntityType.KeyMembers.Count() == 1)
- {
- #>
- this.HasKey(t => t.<#= efHost.EntityType.KeyMembers.Single().Name #>);
- <#
- }
- else
- {
- #>
- this.HasKey(t => new { <#= string.Join(", ", efHost.EntityType.KeyMembers.Select(m => "t." + m.Name)) #> });
- <#
- }
- #>
- // Properties
- <#
- foreach (var prop in efHost.EntityType.Properties)
- {
- var type = (PrimitiveType)prop.TypeUsage.EdmType;
- var isKey = efHost.EntityType.KeyMembers.Contains(prop);
- var storeProp = efHost.PropertyToColumnMappings[prop];
- var sgpFacet = storeProp.TypeUsage.Facets.SingleOrDefault(f => f.Name == "StoreGeneratedPattern");
- var storeGeneratedPattern = sgpFacet == null
- ? StoreGeneratedPattern.None
- : (StoreGeneratedPattern)sgpFacet.Value;
-
- var configLines = new List<string>();
-
- if (type.ClrEquivalentType == typeof(int)
- || type.ClrEquivalentType == typeof(decimal)
- || type.ClrEquivalentType == typeof(short)
- || type.ClrEquivalentType == typeof(long))
- {
- if (isKey && storeGeneratedPattern != StoreGeneratedPattern.Identity)
- {
- configLines.Add(".HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)");
- }
- else if ((!isKey || efHost.EntityType.KeyMembers.Count > 1) && storeGeneratedPattern == StoreGeneratedPattern.Identity)
- {
- configLines.Add(".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)");
- }
- }
-
- if (type.ClrEquivalentType == typeof(string)
- || type.ClrEquivalentType == typeof(byte[]))
- {
- if (!prop.Nullable)
- {
- configLines.Add(".IsRequired()");
- }
-
- var unicodeFacet = (Facet)prop.TypeUsage.Facets.SingleOrDefault(f => f.Name == "IsUnicode");
- if(unicodeFacet != null && !(bool)unicodeFacet.Value)
- {
- configLines.Add(".IsUnicode(false)");
- }
-
- var fixedLengthFacet = (Facet)prop.TypeUsage.Facets.SingleOrDefault(f => f.Name == "FixedLength");
- if (fixedLengthFacet != null && (bool)fixedLengthFacet.Value)
- {
- configLines.Add(".IsFixedLength()");
- }
-
- var maxLengthFacet = (Facet)prop.TypeUsage.Facets.SingleOrDefault(f => f.Name == "MaxLength");
- if (maxLengthFacet != null && !maxLengthFacet.IsUnbounded)
- {
- configLines.Add(string.Format(".HasMaxLength({0})", maxLengthFacet.Value));
- if (storeGeneratedPattern == StoreGeneratedPattern.Computed
- && type.ClrEquivalentType == typeof(byte[])
- && (int)maxLengthFacet.Value == 8)
- {
- configLines.Add(".IsRowVersion()");
- }
- }
- }
-
- if(configLines.Any())
- {
- #>
- this.Property(t => t.<#= prop.Name #>)
- <#= string.Join("\r\n ", configLines) #>;
- <#
- }
- }
- var tableSet = efHost.TableSet;
- var tableName = (string)tableSet.MetadataProperties["Table"].Value
- ?? tableSet.Name;
- var schemaName = (string)tableSet.MetadataProperties["Schema"].Value;
- #>
- // Table & Column Mappings
- <#
- if (schemaName == "dbo" || string.IsNullOrWhiteSpace(schemaName))
- {
- #>
- this.ToTable("<#= tableName #>");
- <#
- }
- else
- {
- #>
- this.ToTable("<#= tableName #>", "<#= schemaName #>");
- <#
- }
- foreach (var property in efHost.EntityType.Properties)
- {
- #>
- this.Property(t => t.<#= property.Name #>).HasColumnName("<#= efHost.PropertyToColumnMappings[property].Name #>");
- <#
- }
-
- // Find m:m relationshipsto configure
- var manyManyRelationships = efHost.EntityType.NavigationProperties
- .Where(np => np.DeclaringType == efHost.EntityType
- && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
- && np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
- && np.RelationshipType.RelationshipEndMembers.First() == np.FromEndMember); // <- ensures we only configure from one end
-
- // Find FK relationships that this entity is the dependent of
- var fkRelationships = efHost.EntityType.NavigationProperties
- .Where(np => np.DeclaringType == efHost.EntityType
- && ((AssociationType)np.RelationshipType).IsForeignKey
- && ((AssociationType)np.RelationshipType).ReferentialConstraints.Single().ToRole == np.FromEndMember);
-
- if(manyManyRelationships.Any() || fkRelationships.Any())
- {
- #>
- // Relationships
- <#
- foreach (var navProperty in manyManyRelationships)
- {
- var otherNavProperty = navProperty.ToEndMember.GetEntityType().NavigationProperties.Where(n => n.RelationshipType == navProperty.RelationshipType && n != navProperty).Single();
- var association = (AssociationType)navProperty.RelationshipType;
- var mapping = efHost.ManyToManyMappings[association];
- var item1 = mapping.Item1;
- var mappingTableName = (string)mapping.Item1.MetadataProperties["Table"].Value
- ?? item1.Name;
- var mappingSchemaName = (string)item1.MetadataProperties["Schema"].Value;
- // Need to ensure that FKs are decalred in the same order as the PK properties on each principal type
- var leftType = (EntityType)navProperty.DeclaringType;
- var leftKeyMappings = mapping.Item2[navProperty.FromEndMember];
- var leftColumns = string.Join(", ", leftType.KeyMembers.Select(m => "\"" + leftKeyMappings[m] + "\""));
- var rightType = (EntityType)otherNavProperty.DeclaringType;
- var rightKeyMappings = mapping.Item2[otherNavProperty.FromEndMember];
- var rightColumns = string.Join(", ", rightType.KeyMembers.Select(m => "\"" + rightKeyMappings[m] + "\""));
- #>
- this.HasMany(t => t.<#= code.Escape(navProperty) #>)
- .WithMany(t => t.<#= code.Escape(otherNavProperty) #>)
- .Map(m =>
- {
- <#
- if (mappingSchemaName == "dbo" || string.IsNullOrWhiteSpace(mappingSchemaName))
- {
- #>
- m.ToTable("<#= mappingTableName #>");
- <#
- }
- else
- {
- #>
- m.ToTable("<#= mappingTableName #>", "<#= mappingSchemaName #>");
- <#
- }
- #>
- m.MapLeftKey(<#= leftColumns #>);
- m.MapRightKey(<#= rightColumns #>);
- });
- <#
- }
-
- foreach (var navProperty in fkRelationships)
- {
- var otherNavProperty = navProperty.ToEndMember.GetEntityType().NavigationProperties.Where(n => n.RelationshipType == navProperty.RelationshipType && n != navProperty).Single();
- var association = (AssociationType)navProperty.RelationshipType;
-
- if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
- {
- #>
- this.HasRequired(t => t.<#= code.Escape(navProperty) #>)
- <#
- }
- else
- {
- #>
- this.HasOptional(t => t.<#= code.Escape(navProperty) #>)
- <#
- }
-
- if(navProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
- {
- #>
- .WithMany(t => t.<#= code.Escape(otherNavProperty) #>)
- <#
- if(association.ReferentialConstraints.Single().ToProperties.Count == 1)
- {
- #>
- .HasForeignKey(d => d.<#= association.ReferentialConstraints.Single().ToProperties.Single().Name #>);
- <#
- }
- else
- {
- #>
- .HasForeignKey(d => new { <#= string.Join(", ", association.ReferentialConstraints.Single().ToProperties.Select(p => "d." + p.Name)) #> });
- <#
- }
- }
- else
- {
- // NOTE: We can assume that this is a required:optional relationship
- // as EDMGen will never create an optional:optional relationship
- // because everything is one:many except PK-PK relationships which must be required
- #>
- .WithOptional(t => t.<#= code.Escape(otherNavProperty) #>);
- <#
- }
- }
- #>
- <#
- }
- #>
- }
- }
- }
|