Esempio n. 1
0
        public override void OnBeforeDelete(IDeleteRequestHandler handler)
        {
            if (ReferenceEquals(null, Target) ||
                (Target.Flags & FieldFlags.Updatable) != FieldFlags.Updatable)
                return;

            if (!attr.ForceCascadeDelete && ServiceQueryHelper.UseSoftDelete(handler.Row))
                return;

            var row = rowFactory();
            var rowIdField = (Field)((row as IIdRow).IdField);

            var deleteHandler = deleteHandlerFactory();
            var deleteList = new List<object>();
            new SqlQuery()
                    .Dialect(handler.Connection.GetDialect())
                    .From(row)
                    .Select((Field)rowIdField)
                    .Where(
                            foreignKeyField == new ValueCriteria(masterKeyField.AsObject(handler.Row)) &
                            queryCriteria)
                    .ForEach(handler.Connection, () =>
                    {
                        deleteList.Add(rowIdField.AsObject(row));
                    });

            foreach (var id in deleteList)
                DeleteDetail(handler.UnitOfWork, id);
        }
Esempio n. 2
0
 protected virtual void ApplyIncludeDeletedFilter(SqlQuery query)
 {
     if (!Request.IncludeDeleted)
     {
         query.Where(ServiceQueryHelper.GetNotDeletedCriteria(Row));
     }
 }
        public override void OnBeforeDelete(IDeleteRequestHandler handler)
        {
            if (ServiceQueryHelper.UseSoftDelete(handler.Row))
            {
                return;
            }

            var idField  = (Field)((handler.Row as IIdRow).IdField);
            var localRow = localRowFactory();

            var deleteList = new List <object>();

            new SqlQuery()
            .Dialect(handler.Connection.GetDialect())
            .From(localRow)
            .Select(localRowIdField)
            .Where(
                foreignKeyField == new ValueCriteria(idField.AsObject(handler.Row)))
            .ForEach(handler.Connection, () =>
            {
                deleteList.Add(localRowIdField.AsObject(localRow));
            });

            foreach (var localId in deleteList)
            {
                DeleteLocalRow(handler.UnitOfWork, localId);
            }
        }
        public override void OnAfterDelete(IDeleteRequestHandler handler)
        {
            if (ServiceQueryHelper.UseSoftDelete(handler.Row))
            {
                return;
            }

            var field        = (StringField)Target;
            var oldFilesJSON = field[handler.Row].TrimToNull();
            var oldFileList  = ParseAndValidate(oldFilesJSON, "oldFiles");

            var filesToDelete = new FilesToDelete();

            UploadHelper.RegisterFilesToDelete(handler.UnitOfWork, filesToDelete);

            foreach (var file in oldFileList)
            {
                DeleteOldFile(filesToDelete, file.Filename);
            }
        }
        public override void OnBeforeDelete(IDeleteRequestHandler handler)
        {
            if (Target is null ||
                (Target.Flags & FieldFlags.Updatable) != FieldFlags.Updatable)
            {
                return;
            }

            if (!attr.ForceCascadeDelete && ServiceQueryHelper.UseSoftDelete(handler.Row))
            {
                return;
            }

            var idField    = handler.Row.IdField;
            var masterId   = idField.AsObject(handler.Row);
            var row        = rowFactory();
            var rowIdField = row.IdField;

            var deleteList = new List <object>();

            new SqlQuery()
            .Dialect(handler.Connection.GetDialect())
            .From(row)
            .Select(rowIdField)
            .Where(
                thisKeyField == new ValueCriteria(masterId) &
                queryCriteria)
            .ForEach(handler.Connection, () =>
            {
                deleteList.Add(rowIdField.AsObject(row));
            });

            foreach (var id in deleteList)
            {
                DeleteDetail(handler.UnitOfWork, id);
            }
        }
 public override void OnBeforeSave(ISaveRequestHandler handler)
 {
     ValidateUniqueConstraint(handler, new Field[] { Target },
                              attr == null ? (string)null : attr.ErrorMessage,
                              attr != null && attr.IgnoreDeleted ? ServiceQueryHelper.GetNotDeletedCriteria(handler.Row) : Criteria.Empty);
 }
Esempio n. 7
0
        protected virtual void ExecuteDelete()
        {
            var isActiveDeletedRow = Row as IIsActiveDeletedRow;
            var isDeletedRow       = Row as IIsDeletedRow;
            var deleteLogRow       = Row as IDeleteLogRow;
            var idField            = (Field)Row.IdField;
            var id = idField.ConvertValue(Request.EntityId, CultureInfo.InvariantCulture);

            if (isActiveDeletedRow == null && isDeletedRow == null && deleteLogRow == null)
            {
                if (new SqlDelete(Row.Table)
                    .WhereEqual(idField, id)
                    .Execute(Connection) != 1)
                {
                    throw DataValidation.EntityNotFoundError(Row, id);
                }
            }
            else
            {
                if (isDeletedRow != null || isActiveDeletedRow != null)
                {
                    var updateLogRow = Row as IUpdateLogRow;
                    var update       = new SqlUpdate(Row.Table)
                                       .WhereEqual(idField, id)
                                       .Where(ServiceQueryHelper.GetNotDeletedCriteria(Row));

                    if (isActiveDeletedRow != null)
                    {
                        update.Set(isActiveDeletedRow.IsActiveField, -1);
                    }
                    else if (isDeletedRow != null)
                    {
                        update.Set(isDeletedRow.IsDeletedField, true);
                    }

                    if (deleteLogRow != null)
                    {
                        update.Set(deleteLogRow.DeleteDateField, DateTimeField.ToDateTimeKind(DateTime.Now,
                                                                                              deleteLogRow.DeleteDateField.DateTimeKind))
                        .Set((Field)deleteLogRow.DeleteUserIdField, Authorization.UserId.TryParseID());
                    }
                    else if (updateLogRow != null)
                    {
                        update.Set(updateLogRow.UpdateDateField, DateTimeField.ToDateTimeKind(DateTime.Now,
                                                                                              updateLogRow.UpdateDateField.DateTimeKind))
                        .Set((Field)updateLogRow.UpdateUserIdField, Authorization.UserId.TryParseID());
                    }

                    if (update.Execute(Connection) != 1)
                    {
                        throw DataValidation.EntityNotFoundError(Row, id);
                    }
                }
                else //if (deleteLogRow != null)
                {
                    if (new SqlUpdate(Row.Table)
                        .Set(deleteLogRow.DeleteDateField, DateTimeField.ToDateTimeKind(DateTime.Now,
                                                                                        deleteLogRow.DeleteDateField.DateTimeKind))
                        .Set((Field)deleteLogRow.DeleteUserIdField, Authorization.UserId.TryParseID())
                        .WhereEqual(idField, id)
                        .Where(new Criteria((Field)deleteLogRow.DeleteUserIdField).IsNull())
                        .Execute(Connection) != 1)
                    {
                        throw DataValidation.EntityNotFoundError(Row, id);
                    }
                }
            }

            InvalidateCacheOnCommit();
        }
Esempio n. 8
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 <LinkingSetRelationAttribute>();
            if (attr == null)
            {
                return(false);
            }

            if (!(row is IIdRow))
            {
                throw new ArgumentException(string.Format("Field '{0}' in row type '{1}' has a [LinkingSetRelation] attribute " +
                                                          "but it doesn't implement IIdRow!",
                                                          Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            var listType = Target.ValueType;

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

            rowType = attr.RowType;
            if (rowType.IsAbstract ||
                !typeof(IRow).IsAssignableFrom(rowType) ||
                rowType.IsInterface)
            {
                throw new ArgumentException(string.Format(
                                                "Field '{0}' in row type '{1}' has a LinkingSetRelationBehavior " +
                                                "but specified row type is not valid row class!",
                                                Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            if (!typeof(IIdRow).IsAssignableFrom(rowType))
            {
                throw new ArgumentException(string.Format(
                                                "Field '{0}' in row type '{1}' has a LinkingSetRelationBehavior " +
                                                "but specified row type doesn't implement IIdRow!",
                                                Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            listFactory = () => (IList)Activator.CreateInstance(listType);
            rowFactory  = () => (IRow)Activator.CreateInstance(rowType);

            var detailRow = rowFactory();

            thisKeyField = detailRow.FindFieldByPropertyName(attr.ThisKey) ??
                           detailRow.FindField(attr.ThisKey);

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

            thisKeyCriteria = new Criteria(thisKeyField.PropertyName ?? thisKeyField.Name);

            itemKeyField = detailRow.FindFieldByPropertyName(attr.ItemKey) ??
                           detailRow.FindField(attr.ItemKey);

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

            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 linking set 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);

            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);
        }
        public bool ActivateFor(Row row)
        {
            if (ReferenceEquals(null, Target))
            {
                return(false);
            }

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

            if (!(row is IIdRow))
            {
                throw new ArgumentException(String.Format("Field '{0}' in row type '{1}' has a LinkingSetRelationBehavior " +
                                                          "but it doesn't implement IIdRow!",
                                                          Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }


            var listType = Target.ValueType;

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

            var rowType = attr.RowType;

            if (rowType.IsAbstract ||
                !typeof(Row).IsAssignableFrom(rowType))
            {
                throw new ArgumentException(String.Format(
                                                "Field '{0}' in row type '{1}' has a LinkingSetRelationBehavior " +
                                                "but specified row type is not valid row class!",
                                                Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            if (!typeof(IIdRow).IsAssignableFrom(rowType))
            {
                throw new ArgumentException(String.Format(
                                                "Field '{0}' in row type '{1}' has a LinkingSetRelationBehavior " +
                                                "but specified row type doesn't implement IIdRow!",
                                                Target.PropertyName ?? Target.Name, row.GetType().FullName));
            }

            listFactory = FastReflection.DelegateForConstructor <IList>(listType);
            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();

            thisKeyField = detailRow.FindFieldByPropertyName(attr.ThisKey) ??
                           detailRow.FindField(attr.ThisKey);

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

            this.thisKeyCriteria = new Criteria(thisKeyField.PropertyName ?? thisKeyField.Name);

            itemKeyField = detailRow.FindFieldByPropertyName(attr.ItemKey) ??
                           detailRow.FindField(attr.ItemKey);

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

            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 linking set 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);

            return(true);
        }
        public override void OnBeforeSave(ISaveRequestHandler handler)
        {
            if (attrList == null)
            {
                return;
            }

            if (attrFields == null)
            {
                attrFields = attrList.Select(attr =>
                {
                    return(attr.Fields.Select(x =>
                    {
                        var field = handler.Row.FindFieldByPropertyName(x) ?? handler.Row.FindField(x);
                        if (ReferenceEquals(null, field))
                        {
                            throw new InvalidOperationException(string.Format(
                                                                    "Can't find field '{0}' of unique constraint in row type '{1}'",
                                                                    x, handler.Row.GetType().FullName));
                        }
                        return field;
                    }));
                }).ToArray();
            }

            for (var i = 0; i < attrList.Length; i++)
            {
                var attr   = attrList[i];
                var fields = attrFields[i];

                UniqueFieldSaveBehavior.ValidateUniqueConstraint(handler, fields, Localizer, attr.ErrorMessage,
                                                                 attrList[i].IgnoreDeleted ? ServiceQueryHelper.GetNotDeletedCriteria(handler.Row) : Criteria.Empty);
            }
        }