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);
     }
 }
Example #2
0
        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);
            }
        }
Example #3
0
        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}')");
            }
        }
Example #4
0
 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);
 }
Example #5
0
        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
 }
Example #7
0
 public virtual void ParentInitialized(EntityClass parent, int index)
 {
 }