Beispiel #1
0
        public SelectQuery <TPoco> Join(string forginColumnName,
                                        [ValueProvider(nameof(JoinMode))] JoinMode joinAs = null)
        {
            var path = PropertyPath <TPoco>
                       .Get(ContainerObject.AccessLayer.Config, forginColumnName)
                       .Where(e => !typeof(IDbCollection).IsAssignableFrom(e.DeclaringType))
                       .Select(e =>
            {
                var dbClassInfoCache = ContainerObject.AccessLayer.GetClassInfo(e.DeclaringType);
                if (dbClassInfoCache.Propertys.ContainsKey(e.Name))
                {
                    return(new KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>(dbClassInfoCache, dbClassInfoCache.Propertys[e.Name]));
                }
                else
                {
                    throw new InvalidOperationException($"The expected property '{e.Name}' was not found.")
                    {
                        Data =
                        {
                            { "Class", dbClassInfoCache }
                        }
                    };
                }
            })
                       .ToArray();

            return(JoinOn(this, path, joinAs));
        }
Beispiel #2
0
        public SelectQuery <TPoco> Join(string forginColumnName,
                                        [ValueProvider(nameof(JoinMode))] JoinMode joinAs = null)
        {
            var path = PropertyPath <TPoco>
                       .Get(ContainerObject.AccessLayer.Config, forginColumnName)
                       .Where(e => !typeof(IDbCollection).IsAssignableFrom(e.DeclaringType))
                       .Select(e =>
            {
                var dbClassInfoCache = ContainerObject.AccessLayer.GetClassInfo(e.DeclaringType);
                return(new KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>(dbClassInfoCache,
                                                                                dbClassInfoCache.Propertys[e.Name]));
            })
                       .ToArray();

            return(JoinOn(path, joinAs));
        }
Beispiel #3
0
        internal static SelectQuery <TPoco> JoinOn(
            IQueryBuilder builder,
            KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>[] path,
            JoinMode joinAs = null,
            Func <ConditionalEvalQuery <TPoco>, ConditionalEvalQuery <TPoco> > joinCondition = null)
        {
            joinAs = joinAs ?? JoinMode.Default;

            IQueryBuilder target      = builder;
            var           targetAlias = target.ContainerObject
                                        .SearchLast <ISelectableQueryPart>(e => !(e is JoinTableQueryPart))
                                        .Alias;
            var parentJoinPart = builder.ContainerObject.Joins;

            foreach (var keyValuePair in path)
            {
                var targetTable = target.ContainerObject.Search(targetAlias);

                var pathOfJoin = target.ContainerObject.GetPathOf(targetAlias) + "." +
                                 keyValuePair.Value.PropertyName;
                var parentAlias = target.ContainerObject
                                  .CreateTableAlias(pathOfJoin);

                var joinExists = parentJoinPart.FirstOrDefault(e => e.Alias.Equals(parentAlias));
                if (joinExists != null)
                {
                    parentJoinPart = joinExists.DependingJoins;
                    targetAlias    = parentAlias;
                    continue;
                }


                Type referenceType;
                if (keyValuePair.Value.CheckForListInterface())
                {
                    referenceType = keyValuePair.Value.PropertyType.GetElementType();
                    if (referenceType == null)
                    {
                        referenceType = keyValuePair.Value.PropertyType.GetGenericArguments().FirstOrDefault();
                    }
                }
                else
                {
                    referenceType = keyValuePair.Value.PropertyType;
                }

                var referencedTypeCache = target.ContainerObject.AccessLayer.GetClassInfo(referenceType);

                var targetAliasOfJoin = new QueryIdentifier
                {
                    QueryIdType = QueryIdentifier.QueryIdTypes.Table,
                    Value       = referencedTypeCache.TableName
                };

                ColumnInfo onSourceTableKey;
                ColumnInfo selfPrimaryKey;

                var referenceColumn = keyValuePair.Value.ForginKeyAttribute?.Attribute;

                if (referenceColumn == null)
                {
                    throw new InvalidOperationException("There is no known reference from table " +
                                                        $"'{keyValuePair.Key.Type}' " +
                                                        "to table " +
                                                        $"'{referenceType}'." +
                                                        "Use a ForeignKeyDeclarationAttribute to connect both");
                }

                var forginColumns = DbAccessLayer.GetSelectableColumnsOf(referencedTypeCache)
                                    .Select(e => new ColumnInfo(e, parentAlias, target.ContainerObject))
                                    .ToList();

                selfPrimaryKey
                    = targetTable.Columns.FirstOrDefault(e => e.IsEquivalentTo(referenceColumn.ForeignKey));
                onSourceTableKey
                    = forginColumns.FirstOrDefault(e => e.IsEquivalentTo(referenceColumn.ReferenceKey));

                var joinTableQueryPart = new JoinTableQueryPart(
                    targetAliasOfJoin,
                    targetAlias,
                    parentAlias,
                    keyValuePair.Key.Type,
                    onSourceTableKey,
                    selfPrimaryKey,
                    forginColumns,
                    keyValuePair.Value,
                    joinAs);

                parentJoinPart.Add(joinTableQueryPart.JoinParseInfo);
                parentJoinPart = joinTableQueryPart.JoinParseInfo.DependingJoins;

                target.ContainerObject.SearchLast <ISelectQueryPart>().AddJoin(joinTableQueryPart);
                target      = target.Add(joinTableQueryPart);
                targetAlias = parentAlias;
            }

            if (joinCondition != null)
            {
                var lastJoin   = target.ContainerObject.SearchLast <JoinTableQueryPart>();
                var condition  = new ConditionStatementQueryPart();
                var tempSelect = new ConditionalEvalQuery <TPoco>(target.Add(condition));
                joinCondition(tempSelect);
                lastJoin.Condition = condition;
            }

            return(new SelectQuery <TPoco>(target));
        }