예제 #1
0
        public static IEnumerable <T> IncludeRelation <T>(this IEnumerable <T> source, string dataSourceName,
                                                          params Expression <Func <T, object> >[] path) where T : DataModel, new()
        {
            var schema = new DataSourceSchema <T>();
            //Table Relations Map
            //To be sent to the DB Lib for SQL Query generation
            var tableRelationsMap = new List <SqlJoinRelation>();

            //This will hold the information about the sub joins object types
            var expressionLookup = new Dictionary <string, string>();

            foreach (var t in path)
            {
                var memberExpression = t.Body as MemberExpression;
                if (memberExpression != null)
                {
                    expressionLookup.Add(memberExpression.Member.Name, t.Body.Type.Name);
                }
            }

            var dbRelationsList = schema.DataFields.Where(field => field.Relation != null &&
                                                          expressionLookup.Values.Contains(
                                                              field.Relation.WithDataModel.Name) &&
                                                          expressionLookup.Keys.Contains(field.Name)
                                                          ).
                                  Select(field => field.Relation).
                                  ToList();


            //Start processing the list of table relations
            if (dbRelationsList.Any())
            {
                //Foreach relation in the relations list, process it and construct the big TablesRelationsMap
                foreach (var relation in dbRelationsList)
                {
                    //Create a temporary map for this target table relation
                    var joinedTableInfo = new SqlJoinRelation();

                    //Get the data model we're in relation with.
                    var relationType = relation.WithDataModel;

                    //Build a data source schema for the data model we're in relation with.
                    var     generalModelSchemaType = typeof(DataSourceSchema <>);
                    var     specialModelSchemaType = generalModelSchemaType.MakeGenericType(relationType);
                    dynamic joinedModelSchema      = Activator.CreateInstance(specialModelSchemaType);

                    //Get it's Data Fields.
                    List <DataField> joinedModelFields = joinedModelSchema.GetDataFields();

                    //Get the table column names - exclude the ID field name.
                    var joinedModelTableColumns = joinedModelFields
                                                  .Where(field => field.TableField != null)
                                                  .Select(field => field.TableField.ColumnName)
                                                  .ToList();

                    //Get the field that describes the relation key from the target model schema
                    var joinedModelKey =
                        joinedModelFields.Find(item => item.TableField != null && item.Name == relation.OnDataModelKey);

                    //Get the field that describes our key on which we are in relation with the target model
                    var thisKey =
                        schema.DataFields.Find(item => item.TableField != null && item.Name == relation.ThisKey);

                    if (thisKey != null && joinedModelKey != null)
                    {
                        //Initialize the temporary map and add it to the original relations map
                        joinedTableInfo.RelationName = relation.RelationName;
                        joinedTableInfo.RelationType = relation.RelationType;


                        joinedTableInfo.MasterTableName    = dataSourceName;
                        joinedTableInfo.MasterTableKey     = thisKey.TableField.ColumnName;
                        joinedTableInfo.JoinedTableName    = joinedModelSchema.GetDataSourceName();
                        joinedTableInfo.JoinedTableKey     = joinedModelKey.TableField.ColumnName;
                        joinedTableInfo.JoinedTableColumns = joinedModelTableColumns;

                        //Add the relation keys to the TableRelationsMap
                        tableRelationsMap.Add(joinedTableInfo);
                    }
                } //end-foreach
            }     //end-outer-if

            //Get our table columns from the schema
            var thisModelTableColumns = schema.DataFields
                                        .Where(field => field.TableField != null)
                                        .Select(
                field => field.TableField.ColumnName)
                                        .ToList();

            var dt = DbRoutines.SELECT_WITH_JOIN(dataSourceName, thisModelTableColumns, null, tableRelationsMap, 0);

            return(dt.ConvertToList(path));
        }
예제 #2
0
        public static T GetWithRelations <T>(this T source, params Expression <Func <T, object> >[] path)
            where T : DataModel, new()
        {
            var schema = new DataSourceSchema <T>();

            // Table Relations Map
            // To be sent to the DB Lib for SQL Query generation
            var tableRelationsMap = new List <SqlJoinRelation>();

            //
            // Database related
            // Where conditions dictionary
            //var finalDataSourceName = string.Empty;
            var whereConditions = new Dictionary <string, object>();


            // This will hold the information about the sub joins object types
            var expressionLookup = path.ToDictionary(t =>
            {
                var memberExpression = t.Body as MemberExpression;
                return(memberExpression != null ? memberExpression.Member.Name : null);
            }, t => t.Body.Type.Name);


            //
            // Get the Relations Fields from the Schema
            var dbRelationsList = schema.DataFields
                                  .Where(field =>
                                         field.Relation != null &&
                                         expressionLookup.Values.Contains(field.Relation.WithDataModel.Name) &&
                                         expressionLookup.Keys.Contains(field.Name))
                                  .Select(field => field.Relation).
                                  ToList();


            //
            // Start processing the list of table relations
            if (dbRelationsList.Any())
            {
                //Foreach relation in the relations list, process it and construct the big TablesRelationsMap
                foreach (var relation in dbRelationsList)
                {
                    //Create a temporary map for this target table relation
                    var joinedTableInfo = new SqlJoinRelation();

                    //Get the data model we're in relation with.
                    var relationType = relation.WithDataModel;

                    //Build a data source schema for the data model we're in relation with.
                    var     generalModelSchemaType = typeof(DataSourceSchema <>);
                    var     specialModelSchemaType = generalModelSchemaType.MakeGenericType(relationType);
                    dynamic joinedModelSchema      = Activator.CreateInstance(specialModelSchemaType);

                    //Get it's Data Fields.
                    List <DataField> joinedModelFields = joinedModelSchema.GetDataFields();

                    //Get the table column names - exclude the ID field name.
                    var joinedModelTableColumns = joinedModelFields
                                                  .Where(field => field.TableField != null)
                                                  .Select(field => field.TableField.ColumnName)
                                                  .ToList();

                    //Get the field that describes the relation key from the target model schema
                    var joinedModelKey =
                        joinedModelFields.Find(item => item.TableField != null && item.Name == relation.OnDataModelKey);

                    //Get the field that describes our key on which we are in relation with the target model
                    var thisKey =
                        schema.DataFields.Find(item => item.TableField != null && item.Name == relation.ThisKey);

                    if (thisKey != null && joinedModelKey != null)
                    {
                        //Initialize the temporary map and add it to the original relations map
                        joinedTableInfo.RelationName       = relation.RelationName;
                        joinedTableInfo.RelationType       = relation.RelationType;
                        joinedTableInfo.MasterTableName    = schema.DataSourceName;
                        joinedTableInfo.MasterTableKey     = thisKey.TableField.ColumnName;
                        joinedTableInfo.JoinedTableName    = joinedModelSchema.GetDataSourceName();
                        joinedTableInfo.JoinedTableKey     = joinedModelKey.TableField.ColumnName;
                        joinedTableInfo.JoinedTableColumns = joinedModelTableColumns;

                        //Add the relation keys to the TableRelationsMap
                        tableRelationsMap.Add(joinedTableInfo);
                    }
                } //end-foreach
            }     //end-outer-if


            //
            // Get the ID Field to find the relations for.
            // If the ID Field was not found, return an empty instance of the object.
            var idField = schema.DataFields.Find(field => field.TableField != null && field.TableField.IsIdField);

            if (idField != null)
            {
                var dataObjectAttr = source.GetType().GetProperty(idField.Name);

                var dataObjectAttrValue = dataObjectAttr.GetValue(source, null);

                // Put the ID Field in the WHERE CONDITIONS
                if (dataObjectAttrValue != null)
                {
                    whereConditions.Add(idField.TableField.ColumnName,
                                        Convert.ChangeType(dataObjectAttrValue, idField.TableField.FieldType));
                }
                else
                {
                    return(source);
                }
            }
            else
            {
                return(source);
            }

            //
            // Get our table columns from the schema
            var thisModelTableColumns = schema.DataFields
                                        .Where(field => field.TableField != null)
                                        .Select(
                field => field.TableField.ColumnName)
                                        .ToList();

            //
            // Query the data-srouce
            var dt = DbRoutines.SELECT_WITH_JOIN(schema.DataSourceName, thisModelTableColumns, whereConditions,
                                                 tableRelationsMap, 1);

            // Return data
            var data = dt.ConvertToList(path);

            if (data != null && data.Count > 0)
            {
                return(data.First());
            }
            return(source);
        }