示例#1
0
        protected static Entity create(EntityClass parent, entitySpec entitySpec, Type type, Action <string> log, bool throwOnCircularReference)
        {
            log?.Invoke($"create: {type.Name} - {entitySpec.name}");

            if (!string.IsNullOrEmpty(entitySpec.aggregation))
            {
                return(new EntityAggregation(entitySpec, log));
            }
            if (!string.IsNullOrEmpty(entitySpec.formula))
            {
                return(new EntityFormula(entitySpec, log));
            }

            var fieldInfo = new LinkedFieldInfo(type, entitySpec.name);

            if (fieldInfo.IEnumerable != null)
            {
                return(new EntityClass(parent, entitySpec, fieldInfo.IEnumerable.GetGenericArguments()[0], fieldInfo, log, throwOnCircularReference));
            }
            if (!entitySpec.AnyNotStar())
            {
                return(new EntityPlainField(entitySpec, fieldInfo, log));
            }

            throw new Exception("Unknown error");
        }
示例#2
0
        public EntityPlainField(entitySpec entitySpec, LinkedFieldInfo fieldInfo, Action <string> log)
            : base(entitySpec)
        {
            log?.Invoke($"EntityPlainField ctor: {entitySpec.name}/{entitySpec.fields?.Count ?? 0} - {fieldInfo.FieldType} ");

            FieldInfo = fieldInfo;
            FieldType = FieldInfo.FieldType;
        }
示例#3
0
 public entitySpec Add(entitySpec entitySpec)
 {
     if (fields == null)
     {
         fields = new List <entitySpec>();
     }
     fields.Add(entitySpec);
     return(this);
 }
示例#4
0
 public DataExtract(Type type, entitySpec entitySpec, ITableManager tableManager = null, Action <string> log = null)
 {
     if (type == null)
     {
         throw new NullReferenceException(nameof(type));
     }
     if (entitySpec == null)
     {
         throw new NullReferenceException(nameof(entitySpec));
     }
     Type         = type;
     TopEntity    = Entity.Create(null, entitySpec, Type, log);
     TableManager = tableManager ?? new InMemoryTableManager();
 }
示例#5
0
 public static EntityClass Create(EntityClass parent, entitySpec entitySpec, Type type, Action <string> log, bool throwOnCircularReference = true)
 {
     return(new EntityClass(
                parent,
                new entitySpec
     {
         name = entitySpec.name ?? type.Name,
         externalname = entitySpec.externalname,
         fields = entitySpec.fields,
         where = entitySpec.where
     },
                type,
                null,
                log,
                throwOnCircularReference));
 }
 public EntityAggregation(entitySpec entitySpec, Action <string> log)
     : base(entitySpec)
 {
     if (string.IsNullOrEmpty(entitySpec.aggregationtype))
     {
         AggregationType = AggregationType.Sum;
     }
     else
     {
         AggregationType = (AggregationType)Enum.Parse(typeof(AggregationType), entitySpec.aggregationtype, true);
     }
     if (string.IsNullOrEmpty(entitySpec.formula))
     {
         return;
     }
     _evaluator = new EvaluateRpn(new Rpn(entitySpec.formula), new List <NameAndType>
     {
         new NameAndType("@", typeof(double))
     });
 }
示例#7
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}')");
            }
        }
示例#8
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 EntityFormula(entitySpec entitySpec, Action <string> log)
     : base(entitySpec)
 {
     log?.Invoke($"EntityFormula ctor: {entitySpec.name}/{entitySpec.fields?.Count ?? 0} - {entitySpec.formula} ");
 }
示例#10
0
 protected Entity(entitySpec entitySpec)
 {
     Spec   = entitySpec;
     NoSave = entitySpec.nosave;
 }