Exemple #1
0
        private static object ToArgs(T value)
        {
            if (info.foreigns.Count == 0)
            {
                return(value);
            }
            DynamicParameters args = new DynamicParameters();

            foreach (var prop in info.locals)
            {
                args.Add(prop.Name, prop.GetValue(value));
            }
            foreach (var prop in info.foreigns)
            {
                object   obj     = prop.GetValue(value);
                var      subInfo = CRUDInfo.Get(prop.PropertyType);
                object[] prims   = subInfo.GetPrimaries(obj);

                int i = 0;
                foreach (var primProp in subInfo.primaries)
                {
                    args.Add($"{prop.Name}{primProp.Name}", prims[i++]);
                }
            }
            return(args);
        }
Exemple #2
0
        private static void ForeignGetInformation(List <string> columns, List <string> tables, List <string> wheres, PropertyInfo info, string prefix)
        {
            CRUDInfo fInfo = CRUDInfo.Get(info.PropertyType);

            string name = prefix + info.Name;

            //column names
            foreach (var local in fInfo.locals)
            {
                columns.Add($"[{name}].[{local.Name}]");
            }

            //where statements
            List <string> ons       = new List <string>();
            string        prevTable = prefix.Length == 0 ? "{0}" : prefix;

            foreach (var primary in fInfo.primaries)
            {
                ons.Add($"[{name}].[{primary.Name}]=[{prevTable}].[{info.Name}{primary.Name}]");
            }

            //table names
            string onString = string.Join(" and ", ons);

            tables.Add($"LEFT JOIN [{info.GetCustomAttribute<ForeignKeyAttribute>().table}] AS [{name}] ON {onString}");

            //foreign info
            foreach (var foreign in fInfo.foreigns)
            {
                ForeignGetInformation(columns, tables, wheres, foreign, name);
            }
        }
Exemple #3
0
        private static void FromArgs(object obj, IEnumerator <object> iter, CRUDInfo info, out bool isNull)
        {
            isNull = false;
            //column names
            foreach (var local in info.locals)
            {
                iter.MoveNext();
                local.SetValue(obj, iter.Current);
                if (iter.Current == null && info.primarySet.Contains(local))
                {
                    isNull = true;
                }
            }

            //foreign info
            foreach (var foreign in info.foreigns)
            {
                CRUDInfo fInfo = CRUDInfo.Get(foreign.PropertyType);
                object   inst  = fInfo.constructor();
                bool     isForeignNull;
                FromArgs(inst, iter, fInfo, out isForeignNull);
                if (isForeignNull)
                {
                    inst = null;
                }
                foreign.SetValue(obj, inst);
            }

            //subquery info
            foreach (var subquery in info.subqueries)
            {
                var attr  = subquery.GetCustomAttribute <ForeignMultiKeyAttribute>();
                var fInfo = CRUDInfo.Get(subquery.PropertyType.GetGenericArguments()[0]);

                string   table     = attr.table;
                string   condition = string.Format(SubquerySQLTemplate, attr.prefix ?? obj.GetType().Name);
                object[] primaries = info.GetPrimaries(obj);

                Condition cond = new Condition(condition, primaries);

                object subqueryObj = fInfo.subqueryConstructor(table, cond);
                subquery.SetValue(obj, subqueryObj);
            }
        }
Exemple #4
0
        private CRUDInfo(Type type)
        {
            ConstructorInfo info = type.GetConstructor(noTypes);

            constructor = () => info.Invoke(noArgs);

            Type            subType = typeof(SubQuery <>).MakeGenericType(type);
            ConstructorInfo subInfo = subType.GetConstructor(subqueryArgs);

            subqueryConstructor = (table, condition) => subInfo.Invoke(new object[] { table, condition });

            foreach (var prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (!prop.HasAttribute <HideAttribute>())
                {
                    if (prop.HasAttribute <ForeignMultiKeyAttribute>())
                    {
                        if (prop.HasAttribute <PrimaryKeyAttribute>())
                        {
                            throw new ArgumentException("[CRUDService] Primary foreign multi keys are not supported!");
                        }
                        if (!prop.PropertyType.IsGenericType || prop.PropertyType.GetGenericTypeDefinition() != typeof(SubQuery <>))
                        {
                            throw new ArgumentException($"[CRUDService] Invalid ForeignMultiKey type for property {prop.Name}. Must be SubQuery<>.");
                        }
                        subqueries.Add(prop);
                    }
                    else
                    {
                        props.Add(prop);
                        if (prop.HasAttribute <PrimaryKeyAttribute>())
                        {
                            primaries.Add(prop);
                        }
                        if (prop.HasAttribute <IdentityAttribute>())
                        {
                            identities.Add(prop);
                        }
                        if (prop.HasAttribute <ForeignKeyAttribute>())
                        {
                            if (prop.HasAttribute <PrimaryKeyAttribute>())
                            {
                                throw new ArgumentException("[CRUDService] Primary foreign keys are not supported!");
                            }
                            foreigns.Add(prop);
                            propNames.AddRange(
                                CRUDInfo.Get(prop.PropertyType).primaries.Select(
                                    primary =>
                                    $"{prop.Name}{primary.Name}"
                                    )
                                );
                        }
                        else
                        {
                            propNames.Add(prop.Name);
                        }
                    }
                }
            }
            locals.AddRange(props);
            var foreignSet = new HashSet <PropertyInfo>(foreigns);

            locals.RemoveAll(value => foreignSet.Contains(value));

            var identitySet = new HashSet <string>(identities.Select(prop => prop.Name));

            createNames.AddRange(
                propNames.Where(name => !identitySet.Contains(name))
                );

            var primaryNameSet = new HashSet <string>(primaries.Select(prop => prop.Name));

            updateNames.AddRange(
                propNames.Where(name => !primaryNameSet.Contains(name))
                );

            primarySet = new HashSet <PropertyInfo>(primaries);
        }