title: Entity Framework : deleting child entities
body: <p>I am using EF, but I have lazy loading disabled. Instead I am using eager loading, so I created my own service:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Generic service for entity framework
  /// &lt;/summary&gt;
  /// &lt;typeparam name="T"&gt;An entity model&lt;/typeparam&gt;
  public class Service&lt;T&gt; : IService&lt;T&gt; where T : class
  {
      // Create our private properties
      private readonly DbContext _context;
      private readonly DbSet&lt;T&gt; _dbEntitySet;
  
      /// &lt;summary&gt;
      /// Default constructor
      /// &lt;/summary&gt;
      /// &lt;param name="context"&gt;The database context&lt;/param&gt;
      public Service(DbContext context)
      {
          // Assign our context and entity set
          _context = context ?? throw new ArgumentNullException("context");
          _dbEntitySet = context.Set&lt;T&gt;();
      }
  
      /// &lt;summary&gt;
      /// Gets all the entities
      /// &lt;/summary&gt;
      /// &lt;param name="includes"&gt;Option includes for eager loading&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public IQueryable&lt;T&gt; List(params string[] includes)
      {
  
          // Create a query
          IQueryable&lt;T&gt; query = _dbEntitySet;
  
          // For each include, append to our query
          if (includes != null)
              foreach (var include in includes)
                  query = query.Include(include);
  
          // Return our query
          return query;
      }
  
      /// &lt;summary&gt;
      /// Creates an entity
      /// &lt;/summary&gt;
      /// &lt;param name="model"&gt;&lt;/param&gt;
      public void Create(T model) =&gt; _dbEntitySet.Add(model);
  
      /// &lt;summary&gt;
      /// Updates an entity
      /// &lt;/summary&gt;
      /// &lt;param name="model"&gt;&lt;/param&gt;
      public void Update(T model) =&gt; _context.Entry&lt;T&gt;(model).State = EntityState.Modified;
  
      /// &lt;summary&gt;
      /// Removes an entity
      /// &lt;/summary&gt;
      /// &lt;param name="model"&gt;&lt;/param&gt;
      public void Remove(T model) =&gt; _context.Entry&lt;T&gt;(model).State = EntityState.Deleted;
  
      /// &lt;summary&gt;
      /// Saves the database context changes
      /// &lt;/summary&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public async Task SaveChangesAsync()
      {
          try
          {
              // Save the changes to the database
              await _context.SaveChangesAsync();
          }
          catch (DbEntityValidationException ex)
          {
  
              // Retrieve the error messages as a list of strings.
              var errorMessages = ex.EntityValidationErrors.SelectMany(x =&gt; x.ValidationErrors).Select(x =&gt; x.ErrorMessage);
  
              // Join the list to a single string.
              var fullErrorMessage = string.Join("; ", errorMessages);
  
              // Combine the original exception message with the new one.
              var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
  
              // Throw a new DbEntityValidationException with the improved exception message.
              throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
          }
          catch (DbUpdateException ex)
          {
              throw;
          }
      }
  
      /// &lt;summary&gt;
      /// Executes a stored procedure in sql
      /// &lt;/summary&gt;
      /// &lt;param name="procedure"&gt;The name of the sproc&lt;/param&gt;
      /// &lt;param name="parameters"&gt;the sql params for the sproc&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public DbRawSqlQuery&lt;T&gt; ExecuteProcedure(string procedure, List&lt;SqlParameter&gt; parameters)
      {
          var results = _context.Database.SqlQuery&lt;T&gt;($"exec {procedure} { CreateQueryStringFromParams(parameters) }");
          return results;
      }
  
      /// &lt;summary&gt;
      /// Dispose
      /// &lt;/summary&gt;
      public void Dispose()
      {
          Dispose(true);
          GC.SuppressFinalize(this);
      }
  
      /// &lt;summary&gt;
      /// Creates the input string to run sprocs in sql with EF by converting the sql params into a nice string
      /// &lt;/summary&gt;
      /// &lt;param name="parameters"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      private static string CreateQueryStringFromParams(IEnumerable&lt;SqlParameter&gt; parameters)
      {
          var response = "";
          var list = parameters as IList&lt;SqlParameter&gt; ?? parameters.ToList();
          var length = list.Count;
  
          for (var i = 0; i &lt; length; i++)
          {
              response += $"{list[i].ParameterName}=\"{list[i].Value}\"";
              if (i != length - 1)
                  response += ", ";
          }
  
          return response;
      }
  
      /// &lt;summary&gt;
      /// Disposes of any attached resources
      /// &lt;/summary&gt;
      /// &lt;param name="disposing"&gt;A boolean indicating whether the object is being disposed&lt;/param&gt;
      protected virtual void Dispose(bool disposing)
      {
  
          // If we are disposing, dispose of our context
          if (disposing)
              _context.Dispose();
      }
  }
  </code></pre>
  
  <p>Each service then inherits this class:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Handles all Group related methods
  /// &lt;/summary&gt;
  public class GroupService : Service&lt;Group&gt;, IGroupService
  {
  
      /// &lt;summary&gt;
      /// The default constructor
      /// &lt;/summary&gt;
      /// &lt;param name="unitOfWork"&gt;&lt;/param&gt;
      public GroupService(DbContext context) : base(context)
      {
      }
  
      /// &lt;summary&gt;
      /// Lists groups by category
      /// &lt;/summary&gt;
      /// &lt;param name="categoryId"&gt;The id of the category&lt;/param&gt;
      /// &lt;param name="includes"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public IQueryable&lt;Group&gt; List(int categoryId, params string[] includes) =&gt; List(includes).Where(m =&gt; m.CategoryId == categoryId);
  
      /// &lt;summary&gt;
      /// Gets a single Group by id
      /// &lt;/summary&gt;
      /// &lt;param name="id"&gt;The id of the Group&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public async Task&lt;Group&gt; GetAsync(int id, params string[] includes) =&gt; await List(includes).Where(model =&gt; model.Id == id).SingleOrDefaultAsync();
  }
  </code></pre>
  
  <p>Each "entity" has a class similar to this <strong>GroupService</strong>.
  I also have <strong>providers</strong> for each entity type too and here is my delete method:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Delete a Group
  /// &lt;/summary&gt;
  /// &lt;param name="id"&gt;The Group id&lt;/param&gt;
  /// &lt;returns&gt;&lt;/returns&gt;
  public async Task&lt;bool&gt; DeleteAsync(int id)
  {
  
      // Get our model
      var model = await _service.GetAsync(id, "Questions");
  
      // For each question, remove from the database
      if (model.Questions != null)
          foreach (var question in model.Questions.ToList())
              if (!await _questionProvider.Value.DeleteAsync(question.Id, false))
                  throw new Exception("Failed to delete the questions");
  
      // Update our Questions
      model.Questions = null;
  
      // Save our model
      _service.Remove(model);
  
      // Save the database changes
      await _service.SaveChangesAsync();
  
      // Return true
      return true;
  }
  </code></pre>
  
  <p>As you can see, I just pull back the questions. </p>
  
  <p>If there are some questions, then I invoke the <strong>questionProvider's</strong> delete method, which is very similar:</p>
  
  <pre><code>/// &lt;summary&gt;
  /// Delete a question
  /// &lt;/summary&gt;
  /// &lt;param name="id"&gt;The question id&lt;/param&gt;
  /// &lt;param name="saveChanges"&gt;Saves the changes to the database after the delete (default true)&lt;/param&gt;
  /// &lt;returns&gt;&lt;/returns&gt;
  public async Task&lt;bool&gt; DeleteAsync(int id, bool saveChanges = true)
  {
  
      // Get our model
      var model = await _service.GetAsync(id, "Answers");
  
      // For each answer, delete from the database
      if (model.Answers != null)
          foreach (var answer in model.Answers.ToList())
              if (!await _answerProvider.Value.DeleteAsync(answer.Id, false))
                  throw new Exception("Failed to delete the answers");
  
      // Update our Answers
      model.Answers = null;
  
      // Save our model
      _service.Remove(model);
  
      // Save the database changes
      if (saveChanges) await _service.SaveChangesAsync();
  
      // Return true
      return true;
  }
  </code></pre>
  
  <p>As you can see, I do not save the context changes until all children have been removed. Now I must point out that I am not removing the child directly from the parent. Instead I am removing the entity from it's own collection and then setting the property to null. After it is all done I save the changes, but I am getting this error:</p>
  
  <blockquote>
    <p>The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.</p>
  </blockquote>
  
  <p>Does anyone know how I can delete the entities in a method similar to what I am trying to achieve?</p>