public void Map(Model.Model model, params IMapperOption[] options) { Mapping.Mapping mapping = new Mapping.Mapping(); mapping.Model = model; foreach (Model.Entity e in model) { Mapping.Entity entityMapping = new Mapping.Entity(); entityMapping.TableName = "Entity"; entityMapping.Add(new Mapping.Attribute("Id") { IsPrimaryKey = true, Generator = SqlMapper.Mapping.Generator.Native, DbType = System.Data.DbType.UInt32 }); entityMapping.Constraint = "Type=='" + e.Type + "'"; foreach (Model.Attribute attribute in e.Attributes.Values) { entityMapping.Add(new Mapping.Attribute(attribute.Name) { TableName = "Attribute", ColumnName = "Name", DbType = driver.GetDbType(attribute.Type) }); } foreach (Model.Reference reference in e.References.Values) { Mapping.Reference referenceMapping = new Mapping.Reference(); referenceMapping.Rules.Add(new Rule() { ParentTableName = "Entity", ParentFieldNames = "Id", ChildTableName = "Relation", ChildFieldNames = "FK_ParentID,Name='" + reference.Name + "'", }); referenceMapping.Rules.Add(new Rule() { ParentTableName = "Relation", ParentFieldNames = "FK_ChildID,Name='" + reference.Name + "'", ChildTableName = "Entity", ChildFieldNames = "Id", }); } } }
public override IDbExpression Visit(EntityExpression item) { if (item.Type != null) currentEntity = mapping.Entities[item.Type]; currentEntityExpression = item; currentAlias = item.Alias; if (item.Expression is NLinq.Expressions.Identifier) { referencePath = new StringBuilder(((NLinq.Expressions.Identifier)item.Expression).Text); if (loadedReferences.ContainsKey(referencePath.ToString())) currentAlias = loadedReferences[referencePath.ToString()]; else loadedReferences.Add(referencePath.ToString(), item.Alias); } if (!inFrom && item.Expression is Evaluant.NLinq.Expressions.MemberExpression) { NLinq.Expressions.Expression expression = Visit(item.Expression); if (expression is IAliasedExpression) currentAlias = ((IAliasedExpression)expression).Alias; return updater.Update(item, expression, currentAlias, item.Type); } if (item.Expression != null && item.Expression.ExpressionType == NLinq.Expressions.ExpressionTypes.AnonymousParameter) { NLinq.Expressions.Expression expression = Visit(item.Expression); return updater.Update(item, Visit(expression), currentAlias, item.Type); } return updater.Update(item, item.Expression, currentAlias, item.Type); }
public override NLinq.Expressions.Expression Visit(NLinq.Expressions.MemberExpression item) { NLinq.Expressions.Expression target = Visit(item.Previous); TableAlias entityAlias = currentAlias; NLinq.Expressions.Expression statement = Visit(item.Statement); if (statement.ExpressionType==NLinq.Expressions.ExpressionTypes.Identifier) { string propertyName = ((Evaluant.NLinq.Expressions.Identifier)statement).Text; if (inFrom && currentEntity.References.ContainsKey(propertyName)) { Mapping.Reference reference = currentEntity.References[propertyName]; TableAlias newTableAlias; IAliasedExpression join = mapping.Mapper.Join(reference, out newTableAlias); //registeredAliasedExpression.Add(join, newTableAlias); lastAliasDefined = ((JoinedTableExpression)join).RightTable.Alias; loadedReferences.Add(referencePath.ToString(), lastAliasDefined); AliasesMapping.Add(newTableAlias, entityAlias); return (NLinq.Expressions.Expression)join; } else { string targetReferencePath = referencePath.ToString().Substring(0, referencePath.Length - propertyName.Length); //If this is not a reference leave the treatment to another visitor if (currentEntity != null && currentEntity.References.ContainsKey(propertyName)) { bool exists = currentFrom == null; Mapping.Reference reference = currentEntity.References[propertyName]; if (!loadedReferences.ContainsKey(referencePath.ToString())) { currentEntity = reference.Target; TableAlias newTableAlias; //New target to reduce the already processed tree target = (NLinq.Expressions.Expression)mapping.Mapper.Join(reference, out newTableAlias); if (reference.IsComposite || loadedReferences.ContainsKey(targetReferencePath)) { target = new LazyAliasResolver(new Dictionary<TableAlias, TableAlias>() { { newTableAlias, currentAlias } }).Visit(target); newTableAlias = currentAlias; //AliasesMapping[loadedReferences[targetReferencePath]] = target.Alias; } //Add JoinedTableExpression to load reference in query if (!exists) target = ((JoinedTableExpression)target).Replace(newTableAlias, currentFrom[0]); else { //Case of Exists in where clause Evaluant.NLinq.Expressions.Expression constraint; target = (NLinq.Expressions.Expression)((JoinedTableExpression)target).Replace(newTableAlias, loadedReferences[targetReferencePath], out constraint); if (this.constraint == null) this.constraint = constraint; else this.constraint = new NLinq.Expressions.BinaryExpression(NLinq.Expressions.BinaryExpressionType.And, this.constraint, constraint); } //if (target == null) // throw new NotSupportedException("The alias specified could not be found"); if (loadedReferences.ContainsKey(targetReferencePath)) target = new LazyAliasResolver(new Dictionary<TableAlias, TableAlias>() { { loadedReferences[targetReferencePath], newTableAlias } }).Visit(target); currentFrom = new FromClause((IAliasedExpression)target); lastAliasDefined = ((JoinedTableExpression)target).RightTable.Alias; loadedReferences.Add(referencePath.ToString(), lastAliasDefined); } else { if (!inFrom) lastAliasDefined = loadedReferences[referencePath.ToString()]; } if (exists) { var constraint = this.constraint; this.constraint = null; return constraint; } return new EntityExpression(lastAliasDefined) { Type = reference.Target.Type }; } //else //{ // if (!loadedReferences.ContainsKey(targetReferencePath)) // return updater.Update(item, target, statement); // //return new ComplexColumnExpression(currentAlias, target is SelectStatement ? new EntityIdentifier(propertyName, currentEntityExpression) : new Evaluant.NLinq.Expressions.Identifier(propertyName)); // return updater.Update(item, target, statement); // //return new ComplexColumnExpression(currentAlias, target is SelectStatement ? new EntityIdentifier(propertyName, new EntityExpression(loadedReferences[targetReferencePath]) { Type = currentEntity.Type }) : new Evaluant.NLinq.Expressions.Identifier(propertyName)); // //return updater.Update(item, target, target is SelectStatement ? new EntityIdentifier(propertyName, new EntityExpression(loadedReferences[targetReferencePath]) { Type = currentEntity.Type }) : new Evaluant.NLinq.Expressions.Identifier(propertyName)); //} } } return updater.Update(item, target, statement); }
public override IDbExpression Visit(EntityExpression item) { if (item.Type != null) currentEntity = mapping.Entities[item.Type]; currentAlias = item.Alias; if (visitingColumns) { if (item.Expression == null) return new ColumnExpression(currentAlias, ColumnExpression.AllColumns); return (IAliasedExpression)Visit(item.Expression); } if (inWhere) { TupleExpression ids = new TupleExpression(); if (currentEntity != null) foreach (Mapping.Attribute id in currentEntity.Ids.Values) ids.Add(new ColumnExpression(currentAlias, id.Field.ColumnName)); return ids; } return base.Visit(item); }
private Mapping.Entity GetEntityMapping(Model.Entity e, params IMapperOption[] options) { if (Mapping.Entities.ContainsKey(e.Type)) return Mapping.Entities[e.Type]; Mapping.Entity em = new Mapping.Entity(); em.Type = e.Type; em.EntityModel = e; Mapping.Entities.Add(em.Type, em); //DefaultStrategy : TablePerHierarchy if (!string.IsNullOrEmpty(e.Inherit)) { Mapping.Entity parentEm = GetEntityMapping(model.Entities[e.Inherit], options); em.TableName = parentEm.TableName; em.Schema = parentEm.Schema; em.Inherit = parentEm; parentEm.Derived.Add(em); SqlMapper.Mapping.InheritanceMappings inheritanceType = SqlMapper.Mapping.InheritanceMappings.TablePerHierarchy; if (em.Inheritance != null) { inheritanceType = em.Inheritance.Type; } switch (inheritanceType) { case Evaluant.Uss.SqlMapper.Mapping.InheritanceMappings.TablePerClass: break; case Evaluant.Uss.SqlMapper.Mapping.InheritanceMappings.TablePerHierarchy: foreach (Mapping.Reference rm in em.Inherit.References.Values) em.Add(rm.Clone(em.Inherit.TableName, em)); foreach (Mapping.Attribute am in em.Inherit.Attributes.Values) em.Add(am.Clone(em.Inherit.TableName, em)); if (em.Inheritance.Discriminator == null) em.Inheritance.Discriminator = "Type=='" + em.Type + "'"; Field[] fields; if (parentEm.Inheritance.Discriminator == null) { parentEm.Inheritance.Discriminator = "Type=='" + parentEm.Type + "'"; fields = GetFields(parentEm.Inheritance.DiscriminatorExpression); foreach (Field field in fields) { parentEm.Add(field); } } fields = GetFields(em.Inheritance.DiscriminatorExpression); foreach (Field field in fields) { em.Add(field); } break; case Evaluant.Uss.SqlMapper.Mapping.InheritanceMappings.TablePerConcreteClass: break; default: break; } } else { em.Schema = e.Type.Substring(0, e.Type.LastIndexOf('.')); em.TableName = e.Type.Substring(em.Schema.Length + 1); } foreach (KeyValuePair<string, Model.Attribute> attribute in e.Attributes) { Mapping.Attribute field = new Mapping.Attribute(attribute.Key); field.Model = attribute.Value; field.ColumnName = attribute.Value.Name; field.IsId = attribute.Value.Name == "Id" || attribute.Value.Name == e.Type.Substring(e.Type.LastIndexOf('.') + 1) + "Id"; field.Name = attribute.Value.Name; field.IsNullable = true; //if (attribute.Key != "#Id") driver.GetTypeInformation(attribute.Value, field); //else //{ // field.DbType = System.Data.DbType.Guid; // field.DefaultValue = Guid.Empty.ToString(); //} em.Add(field); } foreach (KeyValuePair<string, Model.Reference> reference in e.References) { Mapping.Reference rm = new Mapping.Reference(); rm.Name = reference.Value.Name; rm.Model = reference.Value; rm.ChildType = reference.Value.ChildType; //rm.Target = GetEntityMapping(model.Entities[reference.Value.ChildType]); //rm.Cardinality = reference.Value.Cardinality; //rm.Inherited = reference.Value.Inherited; if (reference.Value.Cardinality.IsToMany) { string[] parentFields = new string[em.Ids.Keys.Count]; em.Ids.Keys.CopyTo(parentFields, 0); var target = GetEntityMapping(model.Entities[rm.ChildType]); if (target.Ids.Count == 0) throw new Mapping.MappingException("No Id could be found on the " + target.Type + " entity you need to either specify one or specify manually the way you want to map this reference " + reference.Value); string[] childFields = new string[target.Ids.Keys.Count]; target.Ids.Keys.CopyTo(childFields, 0); string indexSchema = e.Type.Substring(0, e.Type.LastIndexOf('.')); string indexTableName = e.Type.Substring(indexSchema.Length + 1) + "_" + rm.Name; rm.Rules.Add(new Mapping.Rule() { ParentFieldNames = string.Join(",", parentFields), ChildSchema = indexSchema, ChildTableName = indexTableName, ChildFieldNames = "FK_Parent" + string.Join(",FK_Parent", parentFields) }); rm.Rules.Add(new Mapping.Rule() { ParentSchema = indexSchema, ParentTableName = indexTableName, ParentFieldNames = "FK_Child" + string.Join(",FK_Child", childFields), ChildSchema = target.Schema, ChildTableName = target.TableName, ChildFieldNames = string.Join(",", childFields) }); } else { if (reference.Value.Cardinality.IsOne) { var target = GetEntityMapping(model.Entities[rm.ChildType]); string[] parentFields = new string[em.Ids.Keys.Count]; em.Ids.Keys.CopyTo(parentFields, 0); rm.Rules.Add(new Mapping.Rule() { ParentFieldNames = string.Join(",", parentFields), ChildSchema = target.Schema, ChildTableName = target.TableName, ChildFieldNames = "FK_" + em.TableName + string.Join(",FK_" + em.TableName, parentFields) }); } if (reference.Value.Cardinality.IsMany) { var target = GetEntityMapping(model.Entities[rm.ChildType]); string[] childFields = new string[target.Ids.Keys.Count]; target.Ids.Keys.CopyTo(childFields, 0); for (int i = 0; i < childFields.Length; i++) { bool fkMapped = false; foreach (var attr in em.Attributes.Keys) { if ((attr == "FK_" + rm.Name || attr == "FK_" + target.TableName) && childFields.Length == 1 || (attr == "FK_" + rm.Name + childFields[i] || attr == rm.Name + childFields[i] || attr == target.TableName + childFields[i])) { childFields[i] = attr; fkMapped = true; break; } } if (!fkMapped) childFields[i] = "FK_" + target.TableName + childFields[i]; } rm.Rules.Add(new Mapping.Rule() { ParentFieldNames = string.Join("," + target.TableName, childFields), ChildSchema = target.Schema, ChildTableName = target.TableName, ChildFieldNames = string.Join(",", target.Ids.Keys) }); } } em.Add(rm); } return em; }