Example #1
0
        public bool ActivateFor(Row row)
        {
            if (ReferenceEquals(null, Target))
            {
                return(false);
            }

            attr = Target.GetAttribute <MasterDetailRelationAttribute>();
            if (attr == null)
            {
                return(false);
            }

            var rowListType = Target.ValueType;

            if (!rowListType.IsGenericType ||
                rowListType.GetGenericTypeDefinition() != typeof(List <>))
            {
                throw new ArgumentException(String.Format("Field '{0}' in row type '{1}' has a MasterDetailRelationAttribute " +
                                                          "but its property type is not a generic List (e.g. List<Row>)!",
                                                          Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            var rowType = rowListType.GetGenericArguments()[0];

            if (rowType.IsAbstract ||
                !typeof(Row).IsAssignableFrom(rowType))
            {
                throw new ArgumentException(String.Format(
                                                "Field '{0}' in row type '{1}' has a MasterDetailRelationAttribute " +
                                                "but its property type is not a generic list of rows (e.g. List<Row>)!",
                                                Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            rowListFactory = FastReflection.DelegateForConstructor <IList>(rowListType);
            rowFactory     = FastReflection.DelegateForConstructor <Row>(rowType);

            listHandlerFactory = FastReflection.DelegateForConstructor <IListRequestProcessor>(
                typeof(ListRequestHandler <>).MakeGenericType(rowType));

            saveHandlerFactory = FastReflection.DelegateForConstructor <ISaveRequestProcessor>(
                typeof(SaveRequestHandler <>).MakeGenericType(rowType));

            saveRequestFactory = FastReflection.DelegateForConstructor <ISaveRequest>(
                typeof(SaveRequest <>).MakeGenericType(rowType));

            deleteHandlerFactory = FastReflection.DelegateForConstructor <IDeleteRequestProcessor>(
                typeof(DeleteRequestHandler <>).MakeGenericType(rowType));

            var detailRow = rowFactory();

            foreignKeyField = detailRow.FindFieldByPropertyName(attr.ForeignKey) ??
                              detailRow.FindField(attr.ForeignKey);

            if (ReferenceEquals(foreignKeyField, null))
            {
                throw new ArgumentException(String.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                                                          "This field is specified for a master detail relation in field '{2}' of row type '{3}'.",
                                                          attr.ForeignKey, detailRow.GetType().FullName,
                                                          Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            return(true);
        }
Example #2
0
        public bool ActivateFor(Row row)
        {
            if (ReferenceEquals(null, Target))
                return false;

            attr = Target.GetAttribute<MasterDetailRelationAttribute>();
            if (attr == null)
                return false;

            var rowListType = Target.ValueType;
            if (!rowListType.IsGenericType ||
                rowListType.GetGenericTypeDefinition() != typeof(List<>))
            {
                throw new ArgumentException(String.Format("Field '{0}' in row type '{1}' has a MasterDetailRelationAttribute " +
                    "but its property type is not a generic List (e.g. List<Row>)!",
                    Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            var rowType = rowListType.GetGenericArguments()[0];
            if (rowType.IsAbstract ||
                !typeof(Row).IsAssignableFrom(rowType))
            {
                throw new ArgumentException(String.Format(
                    "Field '{0}' in row type '{1}' has a MasterDetailRelationAttribute " +
                    "but its property type is not a generic list of rows (e.g. List<Row>)!",
                        Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            rowListFactory = FastReflection.DelegateForConstructor<IList>(rowListType);
            rowFactory = FastReflection.DelegateForConstructor<Row>(rowType);

            listHandlerFactory = FastReflection.DelegateForConstructor<IListRequestProcessor>(
                typeof(ListRequestHandler<>).MakeGenericType(rowType));

            saveHandlerFactory = FastReflection.DelegateForConstructor<ISaveRequestProcessor>(
                typeof(SaveRequestHandler<>).MakeGenericType(rowType));

            saveRequestFactory = FastReflection.DelegateForConstructor<ISaveRequest>(
                typeof(SaveRequest<>).MakeGenericType(rowType));

            deleteHandlerFactory = FastReflection.DelegateForConstructor<IDeleteRequestProcessor>(
                typeof(DeleteRequestHandler<>).MakeGenericType(rowType));

            if (attr.MasterKeyField != null)
            {
                // Use field from AltIdField
                masterKeyField = row.FindFieldByPropertyName(attr.MasterKeyField) ??
                    row.FindField(attr.MasterKeyField);
                if (ReferenceEquals(masterKeyField, null))
                    throw new ArgumentException(String.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                        "This field is specified for a master detail relation in field '{2}'.",
                        attr.MasterKeyField, row.GetType().FullName,
                        Target.PropertyName ?? Target.Name));
            }
            else
            {
                // Default behaviour: use id field
                masterKeyField = (Field)((row as IIdRow).IdField);
            }

            var detailRow = rowFactory();
            foreignKeyField = detailRow.FindFieldByPropertyName(attr.ForeignKey) ??
                detailRow.FindField(attr.ForeignKey);

            if (ReferenceEquals(foreignKeyField, null))
                throw new ArgumentException(String.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                    "This field is specified for a master detail relation in field '{2}' of row type '{3}'.",
                    attr.ForeignKey, detailRow.GetType().FullName,
                    Target.PropertyName ?? Target.Name, row.GetType().FullName));

            this.foreignKeyCriteria = new Criteria(foreignKeyField.PropertyName ?? foreignKeyField.Name);

            if (!string.IsNullOrEmpty(attr.FilterField))
            {
                this.filterField = detailRow.FindFieldByPropertyName(attr.FilterField) ?? detailRow.FindField(attr.FilterField);
                if (ReferenceEquals(null, this.filterField))
                    throw new ArgumentException(String.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                        "This field is specified for a master detail relation as FilterField in field '{2}' of row type '{3}'.",
                        attr.FilterField, detailRow.GetType().FullName,
                        Target.PropertyName ?? Target.Name, row.GetType().FullName));

                this.filterCriteria = new Criteria(filterField.PropertyName ?? filterField.Name);
                this.filterValue = filterField.ConvertValue(attr.FilterValue, CultureInfo.InvariantCulture);
                if (this.filterValue == null)
                {
                    this.filterCriteria = this.filterCriteria.IsNull();
                    this.queryCriteria = this.filterField.IsNull();
                }
                else
                {
                    this.filterCriteria = this.filterCriteria == new ValueCriteria(this.filterValue);
                    this.queryCriteria = this.filterField == new ValueCriteria(this.filterValue);
                }
            }

            queryCriteria = queryCriteria & ServiceQueryHelper.GetNotDeletedCriteria(detailRow);

            this.includeColumns = new HashSet<string>();

            if (!string.IsNullOrEmpty(attr.IncludeColumns))
                foreach (var s in attr.IncludeColumns.Split(','))
                {
                    var col = s.TrimToNull();
                    if (col != null)
                        this.includeColumns.Add(col);
                }

            return true;
        }
        public bool ActivateFor(IRow row)
        {
            if (Target is null)
            {
                return(false);
            }

            attr = Target.GetAttribute <MasterDetailRelationAttribute>();
            if (attr == null)
            {
                return(false);
            }

            var rowListType = Target.ValueType;

            if (!rowListType.IsGenericType ||
                rowListType.GetGenericTypeDefinition() != typeof(List <>))
            {
                throw new ArgumentException(string.Format("Field '{0}' in row type '{1}' has a MasterDetailRelationAttribute " +
                                                          "but its property type is not a generic List (e.g. List<IRow>)!",
                                                          Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            rowType = rowListType.GetGenericArguments()[0];
            if (rowType.IsAbstract ||
                !typeof(IRow).IsAssignableFrom(rowType) ||
                rowType.IsInterface)
            {
                throw new ArgumentException(string.Format(
                                                "Field '{0}' in row type '{1}' has a MasterDetailRelationAttribute " +
                                                "but its property type is not a generic list of rows (e.g. List<IRow>)!",
                                                Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            rowListFactory = () => (IList)Activator.CreateInstance(rowListType);
            rowFactory     = () => (IRow)Activator.CreateInstance(rowType);

            if (attr.MasterKeyField != null)
            {
                // Use field from AltIdField
                masterKeyField = row.FindFieldByPropertyName(attr.MasterKeyField) ??
                                 row.FindField(attr.MasterKeyField);

                if (masterKeyField is null)
                {
                    throw new ArgumentException(string.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                                                              "This field is specified for a master detail relation in field '{2}'.",
                                                              attr.MasterKeyField, row.GetType().FullName,
                                                              Target.PropertyName ?? Target.Name));
                }
            }
            else
            {
                // Default behaviour: use id field
                masterKeyField = row.IdField;
            }

            var detailRow = rowFactory();

            foreignKeyField = detailRow.FindFieldByPropertyName(attr.ForeignKey) ??
                              detailRow.FindField(attr.ForeignKey);

            if (foreignKeyField is null)
            {
                throw new ArgumentException(string.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                                                          "This field is specified for a master detail relation in field '{2}' of row type '{3}'.",
                                                          attr.ForeignKey, detailRow.GetType().FullName,
                                                          Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            foreignKeyCriteria = new Criteria(foreignKeyField.PropertyName ?? foreignKeyField.Name);

            if (!string.IsNullOrEmpty(attr.FilterField))
            {
                filterField = detailRow.FindFieldByPropertyName(attr.FilterField) ?? detailRow.FindField(attr.FilterField);
                if (filterField is null)
                {
                    throw new ArgumentException(string.Format("Field '{0}' doesn't exist in row of type '{1}'." +
                                                              "This field is specified for a master detail relation as FilterField in field '{2}' of row type '{3}'.",
                                                              attr.FilterField, detailRow.GetType().FullName,
                                                              Target.PropertyName ?? Target.Name, row.GetType().FullName));
                }

                filterCriteria = new Criteria(filterField.PropertyName ?? filterField.Name);
                filterValue    = filterField.ConvertValue(attr.FilterValue, CultureInfo.InvariantCulture);
                if (filterValue == null)
                {
                    filterCriteria = filterCriteria.IsNull();
                    queryCriteria  = filterField.IsNull();
                }
                else
                {
                    filterCriteria = filterCriteria == new ValueCriteria(filterValue);
                    queryCriteria  = filterField == new ValueCriteria(filterValue);
                }
            }

            queryCriteria &= ServiceQueryHelper.GetNotDeletedCriteria(detailRow);

            includeColumns = new HashSet <string>();

            if (!string.IsNullOrEmpty(attr.IncludeColumns))
            {
                foreach (var s in attr.IncludeColumns.Split(','))
                {
                    var col = s.TrimToNull();
                    if (col != null)
                    {
                        includeColumns.Add(col);
                    }
                }
            }

            return(true);
        }