private static object GetMember(EntityMap entityMap, object entityObject, string keyMember) { if (entityMap.HasHelper) { return ((IObjectHelper) entityObject)[keyMember]; } else { try { // Improved Support for Embedded Objects from Chris Schletter (http://www.thzero.com) object memberValue = entityObject; string[] memberParts = keyMember.Split('.'); for (int index = 0; index < memberParts.Length; index++) { string typeName = memberValue.GetType().ToString(); MemberInfo memberField = EntityMap.FindField(typeName, memberParts[index]); if (memberField is FieldInfo) { memberValue = (memberField as FieldInfo).GetValue(memberValue); } else { memberValue = (memberField as PropertyInfo).GetValue(memberValue, null); } } return memberValue; } catch (Exception exception) { throw new ORMapperException("GetField failed for " + keyMember, exception); } } }
private string TS = ";"; // Terminate-Statement Delimiter for SQL Batch #endregion Fields #region Constructors internal Commands(EntityMap entity, CustomProvider provider) { this.QS = provider.StartDelimiter; this.QE = provider.EndDelimiter; this.DD = provider.DateDelimiter; this.GD = provider.GuidDelimiter; this.TS = provider.LineTerminator; this.entity = entity; this.provider = provider; this.selectFields = this.CreateFields(); this.select = this.CreateSelect(); #if DEBUG_MAPPER Debug.WriteLine(" " + this.select); #endif if (!this.entity.ReadOnly) { this.insert = this.CreateInsert(); this.update = this.CreateUpdate(); this.delete = this.CreateDelete(); #if DEBUG_MAPPER Debug.WriteLine(" " + this.insert); Debug.WriteLine(" " + this.update); Debug.WriteLine(" " + this.delete); #endif } }
private Instance(Context context, object entityObject) { this.context = context; string type = entityObject.GetType().ToString(); this.entity = this.context.Mappings[type]; this.commands = this.context.Mappings.Commands(type); this.instance = new WeakReference(entityObject); this.values = new object[this.entity.FieldCount]; }
public static Commands GetCommands(EntityMap entity, CustomProvider customProvider) { if (!customProvider.IsCustom) { switch (customProvider.Provider) { case Provider.MsSql : return new MSCommands(entity, customProvider); case Provider.Sql2005 : return new Sql2005Commands(entity, customProvider); case Provider.Access : return new MSCommands(entity, customProvider); case Provider.Oracle : return new OracleCommands(entity, customProvider); default : return new Commands(entity, customProvider); } } else { return new Commands(entity, customProvider); } }
public object GetObject(Type objectType) { object entityObject = Activator.CreateInstance(objectType, true); EntityMap map = this.Mappings[objectType]; if (map.KeyType != KeyType.User && map.KeyType != KeyType.Composite) { if (map.AutoTrack) { this.StartTracking(entityObject, InitialState.Inserted); } } return(entityObject); }
private string CreateInsert() { if (this.entity.InsertSP.Length == 0) { EntityMap map = this.entity; StringBuilder fieldList = new StringBuilder(); StringBuilder parameterList = new StringBuilder(); for (int index = 0; index < map.FieldCount; index++) { FieldMap field = map[index]; if (field.PersistType == PersistType.Persist) { if (map.KeyType == KeyType.Auto) { if (map.IsAutoKeyMember(field.Member)) { // skip the final key segment of an auto key continue; } } fieldList.Append(this.GetDelimited(this.entity[index].Field) + ", "); parameterList.Append(this.entity[index].Parameter + ", "); } } if (map.TypeField != null && map.TypeField.Length > 0 && map.TypeValue != null && map.TypeValue.ToString().Length > 0) { fieldList.Append(this.GetDelimited(this.entity.TypeField) + ", "); parameterList.Append(this.CleanValue(this.entity.TypeValue) + ", "); } if (fieldList.Length >= 2) { fieldList.Remove(fieldList.Length - 2, 2); } if (parameterList.Length >= 2) { parameterList.Remove(parameterList.Length - 2, 2); } string identity = (this.entity.KeyType == KeyType.Auto ? this.SelectIdentity() : TS); return(String.Format("INSERT INTO {0} ({1}) VALUES ({2}){3}", this.GetDelimited(this.entity.Table), fieldList.ToString(), parameterList.ToString(), identity)); } else { return(this.entity.InsertSP); } }
/// <summary>Advances the ObjectReader to the next record.</summary> /// <returns>True if there are more objects; otherwise, false.</returns> public bool Read() { bool read; if (this.firstRead) { this.firstRead = false; read = this.hasObjects; } else { read = this.data.Read(); } if (read) { if (this.firstLevel) { Internals.LocalStore.Reset(this.objectType); } Internals.EntityMap entity = this.context.Mappings[this.ObjectType]; Type instanceType = this.ObjectType; if (entity.SubTypes.Count > 0) { string typeValue = this.data[entity.TypeField].ToString(); if (entity.SubTypes.ContainsKey(typeValue)) { instanceType = Internals.EntityMap.GetType((string)entity.SubTypes[typeValue]); } } this.current = Activator.CreateInstance(instanceType, true); Internals.Instance instance = new Internals.Instance(this.context, this.current, this.data); if (this.hasEvents) { ((IObjectNotification)this.current).OnMaterialized(this.data); } if (this.context.Mappings[objectType.ToString()].AutoTrack) { this.context.StartTracking(instance); } } else { this.current = null; this.Close(); } return(read); }
private void AddRelation(string member, RelationMap relation) { if (EntityMap.GetType(relation.Type) == null) { throw new MappingException("Mapping: Relation type was Invalid - " + relation.Type); } RelationMap[] tempRelations = new RelationMap[this.relations.Length + 1]; this.relations.CopyTo(tempRelations, 0); tempRelations[this.relations.Length] = relation; this.relations = tempRelations; if (!relation.QueryOnly) { this.AddMember(member); } }
internal EntityMap(string type, string table, string keyMember, KeyType keyType, string sortOrder, bool readOnly, bool changesOnly, bool autoTrack, string typeField, string typeValue) { if (type == null || type.Length == 0) { throw new MappingException("Mapping: Entity type was Missing"); } if (table == null || table.Length == 0) { throw new MappingException("Mapping: Entity table was Missing - " + type); } if (keyType != KeyType.None && (keyMember == null || keyMember.Length == 0)) { throw new MappingException("Mapping: Entity keyMember was Missing - " + type); } this.type = type; this.table = table; this.keyMembers = keyMember.Replace(", ", ",").Split(','); this.keyType = keyType; this.sortOrder = (sortOrder == null ? String.Empty : sortOrder); this.readOnly = readOnly; this.changesOnly = changesOnly; this.autoTrack = autoTrack; this.baseEntity = null; this.typeField = typeField; try { if (typeValue == null) { this.typeValue = null; } else { this.typeValue = int.Parse(typeValue); } } catch { this.typeValue = typeValue.Trim('\''); } if (EntityMap.GetType(this.type) == null) { throw new MappingException("Mapping: Entity type was Invalid - " + type); } if (EntityMap.GetType(this.type).GetInterface(typeof(IObjectHelper).ToString()) != null) { this.hasHelper = true; } if (EntityMap.GetType(this.type).GetInterface(typeof(IObjectNotification).ToString()) != null) { this.hasEvents = true; } }
// <subEntity type="typeName" inherits="baseTypeName" typeValue="typeDiscriminatorValue" /> private void ParseSubEntity(XmlNode subEntityNode, string defaultNamespace, string defaultSchema, string defaultHint) { string type = this.GetTypeName(subEntityNode, "type", defaultNamespace); string inherits = this.GetTypeName(subEntityNode, "inherits", defaultNamespace); string typeValue = this.GetValue(subEntityNode, "typeValue"); EntityMap subEntity = new EntityMap(type, this[inherits], typeValue); foreach (XmlNode attributeNode in subEntityNode.SelectNodes("attribute")) { this.ParseAttribute(subEntity, attributeNode); } foreach (XmlNode attributeNode in subEntityNode.SelectNodes("lookup")) { this.ParseLookup(subEntity, attributeNode, defaultSchema); } foreach (XmlNode attributeNode in subEntityNode.SelectNodes("relation")) { this.ParseRelation(subEntity, attributeNode, defaultNamespace, defaultSchema); } #if DEBUG_MAPPER Debug.WriteLine("SubEntity = " + type + " : " + subEntity.FieldCount.ToString() + " Fields, " + subEntity.RelationCount.ToString() + " Relations"); #endif this.entities.Add(type, subEntity); this.commands.Add(type, ProviderFactory.GetCommands(subEntity, this.provider)); #if DEBUG_MAPPER Debug.WriteLine("SubEntity Inherits = " + inherits + " : " + subEntity.BaseEntity.FieldCount.ToString() + " Fields, " + subEntity.BaseEntity.RelationCount.ToString() + " Relations"); #endif this.commands[inherits] = ProviderFactory.GetCommands(subEntity.BaseEntity, this.provider); string typeName = type.Substring(type.LastIndexOf(".") + 1); if (!this.helper.ContainsKey(typeName)) { this.helper.Add(typeName, type); } else { this.helper[typeName] = null; } }
// Includes Mapping Inheritance by Jim Daugherty and Michael Robin public Commands Commands(string type) { Commands commands = this.commands[type] as Commands; if (commands == null) { // if no commands found then try to find one for ancestor type for (Type baseType = EntityMap.GetType(type).BaseType; baseType != null; baseType = baseType.BaseType) { commands = this.commands[baseType.ToString()] as Commands; if (commands != null) { this.commands[type] = commands; // if found, put into commands so we don't have to do this again break; } } } return(commands); }
private string GetTypeName(XmlNode node, string name, string defaultNamespace) { string typeName = this.GetValue(node, name); if (typeName.IndexOf(',') > 0) { string[] typeParts = typeName.Split(new char[] { ',' }, 2); typeName = FullTypeName(typeParts[0], defaultNamespace); if (typeParts.Length > 1) { EntityMap.GetType(typeName, typeParts[1]); } return(typeName); } else { return(FullTypeName(typeName, defaultNamespace)); } }
// Includes Mapping Inheritance from Jerry Shea (http://www.RenewTek.com) public EntityMap this[string type] { get { EntityMap entity = this.entities[type] as EntityMap; if (entity == null) { // if no entity map found then try to find one for ancestor type for (Type baseType = EntityMap.GetType(type).BaseType; baseType != null; baseType = baseType.BaseType) { entity = this.entities[baseType.ToString()] as EntityMap; if (entity != null) { this.entities[type] = entity; // if found, put into entity map so we don't have to do this again break; } } } return(entity); } }
private static object GetObjectKey(EntityMap entityMap, object entityObject, bool isPersisted) { FieldMap[] keyFields = entityMap.KeyFields; // Paul Welter (http://www.LoreSoft.com) -- allow inserts by using all columns as key if (keyFields.Length == 0 || entityMap.KeyType == KeyType.None) { keyFields = entityMap.Fields; } object[] keyArray = new object[keyFields.Length]; for (int index = 0; index < keyFields.Length; index++) { string keyMember = keyFields[index].Member; object keyValue = GetMember(entityMap, entityObject, keyMember); if (entityMap.KeyType == KeyType.None && keyValue == null) keyValue = string.Empty; if (EntityKey.IsNull(keyValue, isPersisted)) { switch (entityMap.KeyType) { case KeyType.Auto: keyValue = EntityKey.GetAutoKey(keyValue, entityMap.Type); break; case KeyType.Guid: keyValue = EntityKey.GetGuidKey(keyValue is Guid); break; default: throw new ORMapperException("ObjectSpace: Entity Object is missing Key - " + entityMap.Type); } if (entityMap.HasHelper) { ((IObjectHelper) entityObject)[keyMember] = keyValue; } else { if (entityMap.Member(keyMember) is FieldInfo) { (entityMap.Member(keyMember) as FieldInfo).SetValue(entityObject, keyValue); } else { (entityMap.Member(keyMember) as PropertyInfo).SetValue(entityObject, keyValue, null); } } } keyArray[index] = keyValue; } if (keyArray.Length == 1) return keyArray[0]; else return keyArray; }
// Includes Null-Value Assistance from Tim Byng (http://www.missioninc.com) internal void AddField(string member, string field, string nullValue, string alias, string parameter, PersistType persistType, CustomProvider provider) { this.AddMember(member); FieldMap[] tempFields = new FieldMap[this.fields.Length + 1]; this.fields.CopyTo(tempFields, 0); tempFields[this.fields.Length] = new FieldMap(member, field, nullValue, parameter, persistType, EntityMap.GetType(this.Member(member)), provider); int keyIndex = -1; for (int index = 0; index < this.keyMembers.Length; index++) { if (this.keyMembers[index].Equals(member)) { keyIndex = index; } } if (keyIndex > -1) { FieldMap[] tempKeyFields = new FieldMap[this.keyFields.Length + 1]; this.keyFields.CopyTo(tempKeyFields, 0); tempKeyFields[this.keyFields.Length] = tempFields[this.fields.Length]; this.keyFields = tempKeyFields; } if (persistType == PersistType.ReadOnly) { this.readOnlyCount++; } if (persistType == PersistType.Concurrent) { this.concurrentCount++; } this.fields = tempFields; this.helper.Add(alias, this.fields.Length - 1); if (this.baseEntity != null && !this.baseEntity.subFields.ContainsKey(field)) { this.baseEntity.subFields.Add(field, this.fields[this.fields.Length - 1]); } }
// Includes Null-Value Assistance from Tim Byng (http://www.missioninc.com) private void ParseAttribute(EntityMap entity, XmlNode attributeNode) { string member = this.GetValue(attributeNode, "member"); string field = this.GetValue(attributeNode, "field"); // Null Values use nullValue if provided string nullValue = this.GetValue(attributeNode, "nullValue", null); string alias = this.GetValue(attributeNode, "alias", member); // Stored Procedures use parameter if Provided string parameter = this.GetValue(attributeNode, "parameter"); PersistType persistType; // Default persistType is Persist switch (this.GetValue(attributeNode, "persistType", "PERSIST").ToUpper()) { case "READONLY": persistType = PersistType.ReadOnly; break; case "CONCURRENT": persistType = PersistType.Concurrent; break; default: persistType = PersistType.Persist; break; } entity.AddField(member, field, nullValue, alias, parameter, persistType, this.provider); }
public static Commands GetCommands(EntityMap entity, CustomProvider customProvider) { if (!customProvider.IsCustom) { switch (customProvider.Provider) { case Provider.MsSql: return(new MSCommands(entity, customProvider)); case Provider.Sql2005: return(new Sql2005Commands(entity, customProvider)); case Provider.Access: return(new MSCommands(entity, customProvider)); case Provider.Oracle: return(new OracleCommands(entity, customProvider)); default: return(new Commands(entity, customProvider)); } } else { return(new Commands(entity, customProvider)); } }
// Thanks to both Allan Ritchie ([email protected]) // and Gerrod Thomas (http://www.Gerrod.com) for advice and code public object Resync(object entityObject) { EntityMap entity = this.mappings[entityObject.GetType()]; for (int index = 0; index < entity.RelationCount; index++) { RelationMap relation = entity.Relation(index); object member = this[entityObject].GetField(relation.Member); ILoadOnDemand lazy = member as ILoadOnDemand; if (lazy != null) { if (lazy.IsLoaded) { lazy.Resync(); } } } this.EndTracking(entityObject); EntityKey entityKey = new EntityKey(this, entityObject, true); return(this.GetObject(entityObject.GetType(), entityKey.Value, true)); }
internal EntityMap(string type, EntityMap baseEntity, string typeValue) { if (type == null || type.Length == 0) { throw new MappingException("Mapping: SubEntity type was Missing"); } if (baseEntity == null) { throw new MappingException("Mapping: SubEntity inherits was undefined Entity - " + type); } if (baseEntity.TypeField == null || baseEntity.TypeField.Length == 0) { throw new MappingException("Mapping: SubEntity entity had undefined typeField - " + type); } if (typeValue == null || typeValue.Length == 0) { throw new MappingException("Mapping: SubEntity typeValue was not defined - " + type); } this.type = type; this.table = baseEntity.table; this.keyMembers = baseEntity.keyMembers.Clone() as string[]; this.keyType = baseEntity.keyType; this.sortOrder = baseEntity.sortOrder; this.readOnly = baseEntity.readOnly; this.changesOnly = baseEntity.changesOnly; this.autoTrack = baseEntity.autoTrack; this.hint = baseEntity.hint; this.baseEntity = baseEntity; this.typeField = baseEntity.typeField; try { if (typeValue == null) { this.typeValue = null; } else { this.typeValue = int.Parse(typeValue); } } catch { this.typeValue = typeValue.Trim('\''); } baseEntity.AddSubType(this.typeValue.ToString(), type); this.insertSP = baseEntity.insertSP; this.updateSP = baseEntity.updateSP; this.deleteSP = baseEntity.deleteSP; this.readOnlyCount = baseEntity.readOnlyCount; this.concurrentCount = baseEntity.concurrentCount; this.fields = baseEntity.fields.Clone() as FieldMap[]; this.keyFields = baseEntity.keyFields.Clone() as FieldMap[]; this.relations = baseEntity.relations.Clone() as RelationMap[]; this.members = baseEntity.members.Clone() as Hashtable; this.helper = baseEntity.helper.Clone() as Hashtable; if (EntityMap.GetType(this.type) == null) { throw new MappingException("Mapping: Entity type was Invalid - " + type); } if (EntityMap.GetType(this.type).GetInterface(typeof(IObjectHelper).ToString()) != null) { this.hasHelper = true; } if (EntityMap.GetType(this.type).GetInterface(typeof(IObjectNotification).ToString()) != null) { this.hasEvents = true; } }
// Includes Support for Enumerated Member Types from Jerry Shea (http://www.RenewTek.com) internal static object SetField(EntityMap entityMap, object entityObject, string member, object value, CustomProvider provider) { Type type = EntityMap.GetType(entityMap.Member(member)); object typedValue = QueryHelper.ChangeType(value, type); if (entityMap.HasHelper) { try { ((IObjectHelper)entityObject)[member] = typedValue; } catch (Exception exception) { if (typedValue == null) { throw new ORMapperException("ObjectSpace: SetField failed for NULL " + member + " : " + entityMap.Type, exception); } else { throw new MappingException("Mapping: IObjectHelper is missing " + member + " : " + entityMap.Type, exception); } } } else { try { // Improved Support for Embedded Objects from Chris Schletter (http://www.thzero.com) object memberValue = entityObject; string[] memberParts = member.Split('.'); for (int index = 0; index < memberParts.Length; index++) { string typeName = memberValue.GetType().ToString(); MemberInfo memberField = EntityMap.FindField(typeName, memberParts[index]); if (index == memberParts.Length - 1) { if (memberField is FieldInfo) { (memberField as FieldInfo).SetValue(memberValue, typedValue); } else { (memberField as PropertyInfo).SetValue(memberValue, typedValue, null); } } else { if (memberField is FieldInfo) { memberValue = (memberField as FieldInfo).GetValue(memberValue); } else { memberValue = (memberField as PropertyInfo).GetValue(memberValue, null); } } } } catch (Exception exception) { if (typedValue == null) { throw new ORMapperException("ObjectSpace: SetField failed for NULL " + member + " : " + entityMap.Type, exception); } else { throw new ORMapperException("ObjectSpace: SetField failed for " + member + " : " + entityMap.Type, exception); } } } return typedValue; }
internal void AddLookup(string member, string field, string nullValue, string alias, string parameter, string table, string source, string dest, CustomProvider provider) { this.AddMember(member); FieldMap[] tempFields = new FieldMap[this.fields.Length + 1]; this.fields.CopyTo(tempFields, 0); tempFields[this.fields.Length] = new LookupMap(member, field, nullValue, parameter, table, source, dest, EntityMap.GetType(this.Member(member)), provider); this.readOnlyCount++; this.fields = tempFields; this.helper.Add(alias, this.fields.Length - 1); if (this.baseEntity != null && !this.baseEntity.subFields.ContainsKey(field)) { this.baseEntity.subFields.Add(field, this.fields[this.fields.Length - 1]); } }
internal Sql2005Commands(EntityMap entity, CustomProvider provider) : base(entity, provider) { }
internal OracleCommands(EntityMap entity, CustomProvider provider) : base(entity, provider) {}
private void ParseEntity(XmlNode entityNode, string defaultNamespace, string defaultSchema, string defaultHint) { string type = this.GetTypeName(entityNode, "type", defaultNamespace); string table = this.GetTableName(entityNode, "table", defaultSchema); string keyMember = this.GetValue(entityNode, "keyMember"); KeyType keyType; // Default keyType is Auto switch (this.GetValue(entityNode, "keyType", "AUTO").ToUpper()) { case "GUID": keyType = KeyType.Guid; break; case "USER": keyType = KeyType.User; break; case "COMPOSITE": keyType = KeyType.Composite; break; case "NONE": keyType = KeyType.None; break; default: keyType = KeyType.Auto; break; } string sortOrder = this.GetValue(entityNode, "sortOrder"); // Paul Welter (http://www.LoreSoft.com) -- Removed special case for None keyType bool readOnly = true; // Default readOnly is False switch (this.GetValue(entityNode, "readOnly", "FALSE").ToUpper()) { case "TRUE": readOnly = true; break; default: readOnly = false; break; } bool changesOnly; // Default changesOnly is False switch (this.GetValue(entityNode, "changesOnly", "FALSE").ToUpper()) { case "TRUE": changesOnly = true; break; default: changesOnly = false; break; } bool autoTrack; // Default autoTrack is True switch (this.GetValue(entityNode, "autoTrack", "TRUE").ToUpper()) { case "FALSE": autoTrack = false; break; default: autoTrack = true; break; } string hint = this.GetValue(entityNode, "hint", defaultHint); string typeField = this.GetValue(entityNode, "typeField", null); string typeValue = this.GetValue(entityNode, "typeValue", null); EntityMap entity = new EntityMap( type, table, keyMember, keyType, sortOrder, readOnly, changesOnly, autoTrack, hint, typeField, typeValue); // Stored Procedures are Optional but Supported string insertSP = this.GetValue(entityNode, "insertSP"); string updateSP = this.GetValue(entityNode, "updateSP"); string deleteSP = this.GetValue(entityNode, "deleteSP"); entity.AddSProcs(insertSP, updateSP, deleteSP); foreach (XmlNode attributeNode in entityNode.SelectNodes("attribute")) { this.ParseAttribute(entity, attributeNode); } foreach (XmlNode attributeNode in entityNode.SelectNodes("lookup")) { this.ParseLookup(entity, attributeNode, defaultSchema); } foreach (XmlNode attributeNode in entityNode.SelectNodes("relation")) { this.ParseRelation(entity, attributeNode, defaultNamespace, defaultSchema); } #if DEBUG_MAPPER Debug.WriteLine("Entity = " + type + " : " + entity.FieldCount.ToString() + " Fields, " + entity.RelationCount.ToString() + " Relations"); #endif if (keyType != KeyType.None) { // Jeff Lanning ([email protected]): Added length check to prevent "Index Out Of Bounds" exception later during execution (which is very hard to debug). if (entity.KeyFields.Length != keyMember.Split(',').Length) { throw new MappingException("Number of key fields specified for entity '" + type + "' does not matched the number found."); } try { string keyField; foreach (FieldMap f in entity.KeyFields) { keyField = f.Field; } } catch (Exception exception) { throw new MappingException("Mapping: Entity keyMember missing from Attribute members - " + type, exception); } } this.entities.Add(type, entity); this.commands.Add(type, ProviderFactory.GetCommands(entity, this.provider)); string typeName = type.Substring(type.LastIndexOf(".") + 1); if (!this.helper.ContainsKey(typeName)) { this.helper.Add(typeName, type); } else { this.helper[typeName] = null; } }
private OrderByItem ParseItem(OPathLexer lexer, EntityMap entity, OrderByJoinCollection joins, OrderByJoin parentJoin) { Yytoken token = lexer.CurrentToken; if( token.Type != TokenType.IDENT ) { throw new OPathException("'" + token.Text + "' encountered where a property or relationship was expected in sort expression '" + _expression + "'."); } string propertyName = token.Text; token = lexer.Lex(); if( token == null ) { FieldMap field; try { field = entity.GetFieldMap(propertyName); } catch { throw new OPathException(string.Format("The specified property '{0}' in the sort '{1}' is not defined in the entity map for type '{2}'.", propertyName, _expression, entity.Type)); } return new OrderByItem(propertyName, field, true, parentJoin); } if( token.Type != TokenType.PERIOD ) { if( token.Type != TokenType.ASCEND && token.Type != TokenType.DESCEND && token.Type != TokenType.COMMA ) { throw new OPathException("'" + token.Text + "' is not valid in sort expression '" + _expression + "'."); } FieldMap field; try { field = entity.GetFieldMap(propertyName); } catch { throw new OPathException(string.Format("The specified property '{0}' in the sort '{1}' is not defined in the entity map for type '{2}'.", propertyName, _expression, entity.Type)); } bool ascending = (token.Type != TokenType.DESCEND); if( token.Type != TokenType.COMMA ) { lexer.MoveToNext(); } lexer.MoveToNext(); return new OrderByItem(propertyName, field, ascending, parentJoin); } else // dot operator (.) { token = lexer.Lex(); if( token == null ) { throw new OPathException("End of expression encountered where a property or relationship was expected in sort expression '" + _expression + "'."); } if( token.Type != TokenType.IDENT ) { throw new OPathException("'" + token.Text + "' encountered where a property or relationship was expected in sort expression '" + _expression + "'."); } RelationMap relation = entity.Relation(propertyName); if( relation == null ) { throw new OPathException(string.Format("The specified relationship '{0}' in the sort expression '{1}' is not defined in the entity map for type '{2}'.", propertyName, _expression, entity.Type)); } if( relation.Relationship != Relationship.Parent ) { throw new Exception("Relationship '" + relation.Alias + "' is not a ManyToOne relation. Only ManyToOne relations are allowed in sort expressions."); } EntityMap relEntity = _maps[relation.Type]; OrderByJoin join = joins[propertyName]; if( join == null ) { join = new OrderByJoin(relation); joins.Add(join); } // recursive call return ParseItem(lexer, relEntity, join.NestedJoins, join); } }
private void ParseRelation(EntityMap entity, XmlNode attributeNode, string defaultNamespace, string defaultSchema) { Relationship relationship; switch (this.GetValue(attributeNode, "relationship").ToUpper()) { case "ONETOMANY": relationship = Relationship.Child; break; case "MANYTOONE": relationship = Relationship.Parent; break; case "MANYTOMANY": relationship = Relationship.Many; break; default: throw new MappingException("Mapping: Relation relationship is Invalid"); } string member = this.GetValue(attributeNode, "member"); string field = this.GetValue(attributeNode, "field"); string type = this.GetTypeName(attributeNode, "type", defaultNamespace); // Jeff Lanning ([email protected]): Added optional "alias" attribute for use in OPath queries (and to help code generators build entity classes) string alias = this.GetValue(attributeNode, "alias", member); // optional queryOnly is used to enable OPath on relationships without actually loading any relationships -- no member allowed, alias is required bool queryOnly; // Default queryOnly is False switch (this.GetValue(attributeNode, "queryOnly", "FALSE").ToUpper()) { case "TRUE": queryOnly = true; break; default: queryOnly = false; break; } if (!queryOnly) { if (member == null || member.Length == 0) { throw new MappingException("Mapping: Relation attribute 'member' must be specified when 'queryOnly' is set to false - " + entity.Type + " : " + member); } } else { if (member != null && member.Length > 0) { throw new MappingException("Mapping: Relation attribute 'member' is not allowed when 'queryOnly' is set to true - " + entity.Type + " : " + member); } if (alias == null || alias.Length == 0) { throw new MappingException("Mapping: Relation attribute 'alias' must be specified when queryOnly is set to true - " + entity.Type + " : " + type); } member = alias; // Required internally for hashtables, but would be inconsistent if allowed externally } bool lazyLoad; // Default lazyLoad is True switch (this.GetValue(attributeNode, "lazyLoad", "TRUE").ToUpper()) { case "FALSE": lazyLoad = false; break; default: lazyLoad = true; break; } // CascadeDelete help from Ken Muse (http://www.MomentsFromImpact.com) bool cascadeDelete; // Default cascaseDelete is False switch (this.GetValue(attributeNode, "cascadeDelete", "FALSE").ToUpper()) { case "TRUE": cascadeDelete = true; break; default: cascadeDelete = false; break; } string filter = this.GetValue(attributeNode, "filter"); string sortOrder = this.GetValue(attributeNode, "sortOrder"); string selectSP = this.GetValue(attributeNode, "selectSP"); if (relationship == Relationship.Child) { entity.AddChild(member, field, type, alias, queryOnly, lazyLoad, cascadeDelete, filter, sortOrder, selectSP, this.provider); } else if (relationship == Relationship.Parent) { entity.AddParent(member, field, type, alias, queryOnly, lazyLoad, cascadeDelete, filter, sortOrder, selectSP, this.provider); } else { string table = this.GetTableName(attributeNode, "table", defaultSchema); string source = this.GetValue(attributeNode, "sourceField"); string dest = this.GetValue(attributeNode, "destField"); string insertSP = this.GetValue(attributeNode, "insertSP"); string deleteSP = this.GetValue(attributeNode, "deleteSP"); entity.AddMany(member, field, type, alias, table, source, dest, queryOnly, lazyLoad, cascadeDelete, filter, sortOrder, selectSP, insertSP, deleteSP, this.provider); } }
private void ParseEntity(XmlNode entityNode, string defaultNamespace) { string type = this.GetNamespacedValue(entityNode, "type", defaultNamespace); string table = this.GetValue(entityNode, "table"); string keyMember = this.GetValue(entityNode, "keyMember"); KeyType keyType; // Default keyType is Auto switch (this.GetValue(entityNode, "keyType", "AUTO").ToUpper()) { case "GUID": keyType = KeyType.Guid; break; case "USER": keyType = KeyType.User; break; case "COMPOSITE": keyType = KeyType.Composite; break; case "NONE": keyType = KeyType.None; break; default: keyType = KeyType.Auto; break; } string sortOrder = this.GetValue(entityNode, "sortOrder"); // Paul Welter (http://www.LoreSoft.com) -- Removed special case for None keyType bool readOnly = true; // Default readOnly is False switch (this.GetValue(entityNode, "readOnly", "FALSE").ToUpper()) { case "TRUE": readOnly = true; break; default: readOnly = false; break; } bool changesOnly; // Default changesOnly is False switch (this.GetValue(entityNode, "changesOnly", "FALSE").ToUpper()) { case "TRUE": changesOnly = true; break; default: changesOnly = false; break; } bool autoTrack; // Default autoTrack is True switch (this.GetValue(entityNode, "autoTrack", "TRUE").ToUpper()) { case "FALSE": autoTrack = false; break; default: autoTrack = true; break; } string typeField = this.GetValue(entityNode, "typeField", null); string typeValue = this.GetValue(entityNode, "typeValue", null); EntityMap entity = new EntityMap( type, table, keyMember, keyType, sortOrder, readOnly, changesOnly, autoTrack, typeField, typeValue); // Stored Procedures are Optional but Supported string insertSP = this.GetValue(entityNode, "insertSP"); string updateSP = this.GetValue(entityNode, "updateSP"); string deleteSP = this.GetValue(entityNode, "deleteSP"); entity.AddSProcs(insertSP, updateSP, deleteSP); foreach (XmlNode attributeNode in entityNode.SelectNodes("attribute")) { this.ParseAttribute(entity, attributeNode); } foreach (XmlNode attributeNode in entityNode.SelectNodes("lookup")) { this.ParseLookup(entity, attributeNode); } foreach (XmlNode attributeNode in entityNode.SelectNodes("relation")) { this.ParseRelation(entity, attributeNode, defaultNamespace); } #if DEBUG_MAPPER Debug.WriteLine("Entity = " + type + " : " + entity.FieldCount.ToString() + " Fields, " + entity.RelationCount.ToString() + " Relations"); #endif if (keyType != KeyType.None) { // Jeff Lanning ([email protected]): Added length check to prevent "Index Out Of Bounds" exception later during execution (which is very hard to debug). if (entity.KeyFields.Length != keyMember.Split(',').Length) { throw new MappingException("Number of key fields specified for entity '" + type + "' does not matched the number found."); } try { string keyField; foreach (FieldMap f in entity.KeyFields) keyField = f.Field; } catch (Exception exception) { throw new MappingException("Mapping: Entity keyMember missing from Attribute members - " + type, exception); } } this.entities.Add(type, entity); this.commands.Add(type, ProviderFactory.GetCommands(entity, this.provider)); string typeName = type.Substring(type.LastIndexOf(".") + 1); if (!this.helper.ContainsKey(typeName)) { this.helper.Add(typeName, type); } else { this.helper[typeName] = null; } }
internal object GetField(EntityMap entityMap, string member) { return Instance.GetField(this.entity, this.EntityObject, member); }
internal object SetField(EntityMap entityMap, string member, object value) { return Instance.SetField(this.entity, this.EntityObject, member, value, this.context.Provider); }
private void ParseRelation(EntityMap entity, XmlNode attributeNode, string defaultNamespace) { Relationship relationship; switch (this.GetValue(attributeNode, "relationship").ToUpper()) { case "ONETOMANY": relationship = Relationship.Child; break; case "MANYTOONE": relationship = Relationship.Parent; break; case "MANYTOMANY": relationship = Relationship.Many; break; default: throw new MappingException("Mapping: Relation relationship is Invalid"); } string member = this.GetValue(attributeNode, "member"); string field = this.GetValue(attributeNode, "field"); string type = this.GetNamespacedValue(attributeNode, "type", defaultNamespace); // Jeff Lanning ([email protected]): Added optional "alias" attribute for use in OPath queries (and to help code generators build entity classes) string alias = this.GetValue(attributeNode, "alias", member); // optional queryOnly is used to enable OPath on relationships without actually loading any relationships -- no member allowed, alias is required bool queryOnly; // Default queryOnly is False switch (this.GetValue(attributeNode, "queryOnly", "FALSE").ToUpper()) { case "TRUE": queryOnly = true; break; default: queryOnly = false; break; } if (!queryOnly) { if (member == null || member.Length == 0) { throw new MappingException("Mapping: Relation attribute 'member' must be specified when 'queryOnly' is set to false - " + entity.Type + " : " + member); } } else { if (member != null && member.Length > 0) { throw new MappingException("Mapping: Relation attribute 'member' is not allowed when 'queryOnly' is set to true - " + entity.Type + " : " + member); } if (alias == null || alias.Length == 0) { throw new MappingException("Mapping: Relation attribute 'alias' must be specified when queryOnly is set to true - " + entity.Type + " : " + type); } member = alias; // Required internally for hashtables, but would be inconsistent if allowed externally } bool lazyLoad; // Default lazyLoad is True switch (this.GetValue(attributeNode, "lazyLoad", "TRUE").ToUpper()) { case "FALSE": lazyLoad = false; break; default: lazyLoad = true; break; } // CascadeDelete help from Ken Muse (http://www.MomentsFromImpact.com) bool cascadeDelete; // Default cascaseDelete is False switch (this.GetValue(attributeNode, "cascadeDelete", "FALSE").ToUpper()) { case "TRUE": cascadeDelete = true; break; default: cascadeDelete = false; break; } string filter = this.GetValue(attributeNode, "filter"); string selectSP = this.GetValue(attributeNode, "selectSP"); if (relationship == Relationship.Child) { entity.AddChild(member, field, type, alias, queryOnly, lazyLoad, cascadeDelete, filter, selectSP, this.provider); } else if (relationship == Relationship.Parent) { entity.AddParent(member, field, type, alias, queryOnly, lazyLoad, cascadeDelete, filter, selectSP, this.provider); } else { string table = this.GetValue(attributeNode, "table"); string source = this.GetValue(attributeNode, "sourceField"); string dest = this.GetValue(attributeNode, "destField"); string insertSP = this.GetValue(attributeNode, "insertSP"); string deleteSP = this.GetValue(attributeNode, "deleteSP"); entity.AddMany(member, field, type, alias, table, source, dest, queryOnly, lazyLoad, cascadeDelete, filter, selectSP, insertSP, deleteSP, this.provider); } }
private Join[] GetJoinsFromOrderBy(EntityMap sourceEntity, string sourceAlias, OrderBy node) { // traverse the join tree, building a flat array of Join objects ArrayList joinList = new ArrayList(); AddOrderByJoinsToList(joinList, sourceEntity, sourceAlias, node.OrderByJoins, 1); return (Join[])joinList.ToArray(typeof(Join)); }
private void AddOrderByJoinsToList(ArrayList joinList, EntityMap sourceEntity, string sourceAlias, OrderByJoinCollection joins, int indentDepth) { foreach( OrderByJoin join in joins ) { RelationMap relation = join.RelationMap; if( relation.Relationship != Relationship.Parent ) { throw new Exception("Relationship '" + relation.Alias + "' is not a ManyToOne relation. Only ManyToOne relations are allowed in sort expressions."); } EntityMap joinEntity = _maps[relation.Type]; join.Alias = GetNextAlias(); string relationConstraint = ReplaceTableNameWithAlias(relation.Filter, sourceEntity.Table, sourceAlias); relationConstraint = ReplaceTableNameWithAlias(relationConstraint, joinEntity.Table, join.Alias); StringWriter joinCondition = new StringWriter(); bool whereStarted = false; WriteJoinCondition(joinCondition, sourceAlias, relation.Fields, join.Alias, GetFieldNames(joinEntity.KeyFields), relationConstraint, false, ref whereStarted); joinList.Add( new Join(joinEntity.Table, join.Alias, joinCondition.ToString(), indentDepth)); // traverse inner joins using a recursive call if( join.NestedJoins.Count > 0 ) { AddOrderByJoinsToList(joinList, joinEntity, join.Alias, join.NestedJoins, indentDepth + 1); } } }
private void ParseLookup(EntityMap entity, XmlNode attributeNode) { string member = this.GetValue(attributeNode, "member"); string field = this.GetValue(attributeNode, "field"); string nullValue = this.GetValue(attributeNode, "nullValue", null); string alias = this.GetValue(attributeNode, "alias", member); string table = this.GetValue(attributeNode, "table"); string source = this.GetValue(attributeNode, "foreignKey"); string dest = this.GetValue(attributeNode, "lookupKey"); string parameter = this.GetValue(attributeNode, "parameter"); entity.AddLookup(member, field, nullValue, alias, parameter, table, source, dest, this.provider); }
internal OracleCommands(EntityMap entity, CustomProvider provider) : base(entity, provider) { }
// <subEntity type="typeName" inherits="baseTypeName" typeValue="typeDiscriminatorValue" /> private void ParseSubEntity(XmlNode subEntityNode, string defaultNamespace) { string type = this.GetNamespacedValue(subEntityNode, "type", defaultNamespace); string inherits = this.GetNamespacedValue(subEntityNode, "inherits", defaultNamespace); string typeValue = this.GetValue(subEntityNode, "typeValue"); EntityMap subEntity = new EntityMap(type, this[inherits], typeValue); foreach (XmlNode attributeNode in subEntityNode.SelectNodes("attribute")) { this.ParseAttribute(subEntity, attributeNode); } foreach (XmlNode attributeNode in subEntityNode.SelectNodes("lookup")) { this.ParseLookup(subEntity, attributeNode); } foreach (XmlNode attributeNode in subEntityNode.SelectNodes("relation")) { this.ParseRelation(subEntity, attributeNode, defaultNamespace); } #if DEBUG_MAPPER Debug.WriteLine("SubEntity = " + type + " : " + subEntity.FieldCount.ToString() + " Fields, " + subEntity.RelationCount.ToString() + " Relations"); #endif this.entities.Add(type, subEntity); this.commands.Add(type, ProviderFactory.GetCommands(subEntity, this.provider)); #if DEBUG_MAPPER Debug.WriteLine("SubEntity Inherits = " + inherits + " : " + subEntity.BaseEntity.FieldCount.ToString() + " Fields, " + subEntity.BaseEntity.RelationCount.ToString() + " Relations"); #endif this.commands[inherits] = ProviderFactory.GetCommands(subEntity.BaseEntity, this.provider); string typeName = type.Substring(type.LastIndexOf(".") + 1); if (!this.helper.ContainsKey(typeName)) { this.helper.Add(typeName, type); } else { this.helper[typeName] = null; } }
private void WriteSelectClause(TextWriter w, EntityMap entity, string entityAlias, out Join[] lookupJoins) { w.Write("SELECT "); int columnCount = 0; ArrayList joins = new ArrayList(); ArrayList joinMaps = new ArrayList(); // add all core entity fields and lookup columns for( int i = 0; i < entity.Fields.Length; i++ ) { if( columnCount > 0 ) w.Write(", "); FieldMap field = entity.Fields[i]; if( !field.IsLookup ) { WriteSqlColumn(w, entityAlias, field.Field); } else // lookup column { LookupMap lookup = (LookupMap)field; // see if we already have a join setup for the table associated to this lookup field string tableAlias = null; for( int j = 0; j < joinMaps.Count; j++ ) { if( CanLookupMapsUseSameJoin((LookupMap)joinMaps[j], lookup) ) { tableAlias = (joins[j] as Join).TableAlias; break; } } // create a new join if an existing one was not found above if( tableAlias == null ) { tableAlias = GetNextAlias(); StringWriter joinCondition = new StringWriter(); bool whereStarted = false; WriteJoinCondition(joinCondition, entityAlias, lookup.Source, tableAlias, lookup.Dest, null, false, ref whereStarted); joins.Add( new Join(lookup.Table, tableAlias, joinCondition.ToString(), 1) ); joinMaps.Add(lookup); } WriteSqlColumn(w, tableAlias, lookup.Field, lookup.FieldAlias); // add lookup to the map - in case we need the alias later during query generation _lookupFieldToAliasMap.Add(lookup.FieldAlias, tableAlias); } columnCount += 1; } // add any sub fields if( entity.SubFields.Keys.Count > 0 ) { foreach( string subField in entity.SubFields.Keys ) { if( columnCount > 0 ) w.Write(", "); WriteSqlColumn(w, entityAlias, subField); columnCount += 1; } } // add type field if specified if( entity.TypeField != null && entity.TypeField.Length > 0 ) { if( columnCount > 0 ) w.Write(", "); WriteSqlColumn(w, entityAlias, entity.TypeField); columnCount += 1; } // return our array of joins lookupJoins = (Join[])joins.ToArray(typeof(Join)); }