public EntityWithTable( EntityClass entity, ITableManager t, bool isTopTable = true) { Entity = entity; if (!Entity.NoSave) { Table = t.New(entity, isTopTable, !Entity.Lists.Any(), entity.PrimaryKeyIndex); } foreach (var e in entity.Lists) { Lists.Add(new EntityWithTable(e, t, false)); } if (entity.AggregationFields.Any()) { Aggregator = new Aggregator(entity.AggregationFields.ToArray(), entity.ParentEffectiveFieldCount); } }
public SqlTable( ITableManager tableManager, EntityClass entity, bool isTopTable, bool isLeafTable, int primaryKeyIndex, int flushThreshold) { TableManager = tableManager; _flushThreshold = flushThreshold; Name = entity.TableName; IsTopTable = isTopTable; IsLeafTable = isLeafTable; PrimaryKeyIndex = primaryKeyIndex; Fields = entity.Fields.Where(_ => !_.NoSave).Select(_ => new NameAndType(_.ExternalName, _.FieldType)).ToList(); if (Fields.Any(_ => string.IsNullOrEmpty(_.Name))) { throw new ArgumentException($"Table {Name} contains empty column name"); } _dataTable = new DataTable(); if (AutomaticPrimaryKey) { _dataTable.Columns.Add("_id_", typeof(Guid)).AllowDBNull = false; } if (!IsTopTable) { ForeignKeyName = entity.ForeignKeyName; var dc = _dataTable.Columns.Add(ForeignKeyName, entity.ForeignKeyType); if (entity.ForeignKeyType == typeof(string)) { dc.MaxLength = 100; } dc.AllowDBNull = false; } foreach (var field in Fields) { var dc = _dataTable.Columns.Add(field.Name, LinkedFieldInfo.StripNullable(field.Type)); dc.AllowDBNull = field.Type == typeof(string) || field.Type == typeof(byte[]) || field.Type != LinkedFieldInfo.StripNullable(field.Type); } }
public EntityClass( EntityClass parent, entitySpec entitySpec, Type type, LinkedFieldInfo fieldInfo, Action <string> log, bool throwOnCircularReference) : base(entitySpec) { log?.Invoke( $"EntityClass ctor: {entitySpec.name}/{entitySpec.fields?.Count ?? 0} - {type?.Name} - {fieldInfo?.FieldType} - {fieldInfo?.IEnumerable?.Name}"); TableName = parent != null && Spec.externalname == null ? string.Join("_", parent.TableName, ExternalName) : ExternalName; FieldInfo = fieldInfo; FieldType = fieldInfo?.FieldType; if (!Spec.Any() || isStarExpansionAndNoRealSubProperties(type)) { // not sure if this should be allowed... Fields.Add(new EntitySolitaire(type)); } breakDownSubEntities(type, log, throwOnCircularReference); // move the nosave fields to always be at the end of the list var noSaveFields = Fields.Where(_ => _.NoSave).ToList(); Fields.RemoveAll(_ => _.NoSave); SaveableFieldCount = Fields.Count; Fields.AddRange(noSaveFields); // this is temporary - to be able to serialze a contract with "*" since it was digging up so much garbage... // need to investigae each "garbage" occurrence and handle it more elegantly Fields.RemoveAll(_ => _ is EntityPlainField && SqlHelpers.Field2Sql(_.NameAndType.Name, _.NameAndType.Type, false, 0, true) == null); Lists.RemoveAll(_ => !_.Fields.Any() && !_.Lists.Any()); if (Fields.Count(_ => _.Spec.primarykey) > 1) { throw new Exception("There may be no more than one primary key field"); } PrimaryKeyIndex = Fields.FindIndex(_ => _.Spec.primarykey); EffectiveFieldCount = Fields.Count + 1; for (var fi = 0; fi < Fields.Count; fi++) { Fields[fi].ParentInitialized(this, fi); } for (var li = 0; li < Lists.Count; li++) { Lists[li].ParentInitialized(this, li); } for (var i = 0; i < Fields.Count; i++) { Fields[i].ResultSetIndex = i; } var fieldsThenFormulas = Fields.Where(_ => !(_ is EntityAggregation)).ToList(); SortWithFormulasLast(fieldsThenFormulas); _fieldsThenNonAggregatedFormulas = fieldsThenFormulas.Where(_ => !_.IsBasedOnAggregation).ToArray(); _aggregatedFormulas = fieldsThenFormulas.Where(_ => _.IsBasedOnAggregation).ToArray(); if (!string.IsNullOrEmpty(Spec.where)) { _whereClause = new WhereClause(Spec.where, Fields, _fieldsThenNonAggregatedFormulas); } if (PrimaryKeyIndex >= 0 && Fields[PrimaryKeyIndex].IsBasedOnAggregation) { throw new Exception($"The primary key must not be based on an aggregation (table '{TableName}')"); } }
public override void ParentInitialized(EntityClass parent, int index) { ParentEffectiveFieldCount = parent.EffectiveFieldCount; ForeignKeyType = parent.PrimaryKeyIndex < 0 ? typeof(Guid) : parent.Fields[parent.PrimaryKeyIndex].FieldType; ForeignKeyName = string.Join("_", parent.TableName, parent.PrimaryKeyName); }
private static IEnumerable <Entity> expansionOverStar( Action <string> log, EntityClass parent, Type masterType, entitySpec subEntitySpec, HashSet <Type> detectCircularRef, bool throwOnCircularReference, string prefix = "", Type subType = null) { if (subEntitySpec.name != "*") { yield return(create(parent, subEntitySpec, masterType, log, throwOnCircularReference)); yield break; } subType = subType ?? masterType; if (detectCircularRef.Contains(subType)) { if (throwOnCircularReference) { throw new Exception("Circular reference detected while processing inclusion of all fields ('*')"); } else { yield return(new EntityClass(parent, entitySpec.Begin(prefix.TrimEnd(".".ToCharArray())), masterType, null, log, true)); yield break; } } detectCircularRef.Add(subType); foreach (var nameAndType in LinkedFieldInfo.GetAllFieldsAndProperties(subType)) { if (nameAndType.Type == typeof(object)) { continue; } var spec = entitySpec.Begin(prefix + nameAndType.Name); var subProperties = LinkedFieldInfo.GetAllFieldsAndProperties(nameAndType.Type); if (LinkedFieldInfo.CheckForIEnumerable(nameAndType.Type) != null) { spec.Add("*"); yield return(create(parent, spec, masterType, log, throwOnCircularReference)); } else if (!subProperties.Any()) { yield return(create(parent, spec, masterType, log, throwOnCircularReference)); } foreach (var liftedSubProperty in subProperties) { if (liftedSubProperty.Type == typeof(object)) { continue; } var propName = $"{prefix}{nameAndType.Name}.{liftedSubProperty.Name}"; if (LinkedFieldInfo.GetAllFieldsAndProperties(liftedSubProperty.Type).Any()) { foreach (var q in expansionOverStar(log, parent, masterType, "*", detectCircularRef, throwOnCircularReference, propName + ".", liftedSubProperty.Type)) { yield return(q); } } else { yield return(create(parent, entitySpec.Begin(propName).Add("*"), masterType, log, throwOnCircularReference)); } //yield return create(propName, masterType, log); } } detectCircularRef.Remove(subType); }
public ConcurrentEntityTableDictionary(ITableManager tableManager, EntityClass template) { _tableManager = tableManager; _template = template; GetOrNew(Thread.CurrentThread.ManagedThreadId); // force creation of the first table set on current thread }
public virtual void ParentInitialized(EntityClass parent, int index) { }