/// <summary> /// Resolves dependency constraints. /// </summary> /// <param name="entity">The entity.</param> /// <param name="entitiesToDelete">The entities to delete.</param> /// <returns>Returns a list of contraints.</returns> protected virtual List <string> ResolveDependencyConstraints(Entity entity, List <Entity> entitiesToDelete) { var constraints = new List <string>(); var entityType = entity.GetType(); var entityMetadataList = EntityMetadataResolver.EntityMetadata.Where(x => x.Fields.Any(y => y.FieldType == entityType.Name && y.Mandatory)); foreach (var entityMetadata in entityMetadataList) { var currentType = EntityMetadataResolver.GetEntityType(entityMetadata); var fields = entityMetadata.Fields.Where(x => x.FieldType == entityType.Name && x.Mandatory); var parameter = Expression.Parameter(currentType, "x"); Expression resultExpression = null; foreach (var field in fields) { var body = Expression.Equal(Expression.Property(parameter, field.Name), Expression.Constant(entity.Id)); resultExpression = resultExpression == null ? body : Expression.OrElse(resultExpression, body); } var finalExpression = Expression.Lambda(resultExpression, parameter); var queryable = new QueryProvider(this).CreateQuery(Expression.Constant(null, typeof(IQueryable <>).MakeGenericType(currentType))); var methodInfo = typeof(Queryable).GetMethods().FirstOrDefault(x => x.Name == "Where").MakeGenericMethod(currentType); var methodCall = Expression.Call(methodInfo, queryable.Expression, finalExpression); queryable = queryable.Provider.CreateQuery(methodCall); var results = queryable.Cast <Entity>().ChangeQueryType(currentType).ToList().Except(entitiesToDelete).ToList(); if (results.Count > 0) { constraints.AddRange(results.Select(x => $"Entity '{entityMetadata.Name}' with Id = '{x.Id}' references '{entityType.Name}' in {string.Join(", ", fields.Select(y => $"'{y.Name}'"))}.")); } } return(constraints); }