1
\$\begingroup\$

I have this ef 6 delete method where I build <List> the related entities that will need to be deleted. Then I use RemoveRange to remove then. Once its deleted I will need to re-order the data and update the SequenceOrder field.

public ResultStatus DeleteMeetingPollingQuestion(int MeetingPollingQuestionId)
{
     using (var db = new NccnEcommerceEntities())
    {
        using (DbContextTransaction dbTran = db.Database.BeginTransaction())
        {

            ResultStatus result = new ResultStatus();

            try
            {
                var MeetingPollingQuestions = db.MeetingPollingQuestions.Find(MeetingPollingQuestionId);
                

                if (MeetingPollingQuestions != null)
                {
                    int? reorderinMeetingPollingId = MeetingPollingQuestions.MeetingPollingId;
                    var deleteMeetingPollingParts = db.MeetingPollingParts
                    .Where(task => task.MeetingPollingQuestionId == MeetingPollingQuestionId)
                    .ToList();

                    List<MeetingPollingPartsValue> deleteMeetingPollingPartsValues = new List<MeetingPollingPartsValue>();
                    foreach (var MeetingPollingParts in deleteMeetingPollingParts)
                    {
                        int MeetingPollingPartsId = MeetingPollingParts.MeetingPollingPartsId;
                        var MeetingPollingPartsValue = db.MeetingPollingPartsValues.Where(x => x.MeetingPollingPartsId == MeetingPollingPartsId).ToList();
                        deleteMeetingPollingPartsValues.AddRange(MeetingPollingPartsValue);
                    }

                    List<EFModel.MeetingPollingPartsValuesImage> deleteMeetingPollingPartsValuesImages = new List<EFModel.MeetingPollingPartsValuesImage>();
                    foreach (var MeetingPollingPartsValue in deleteMeetingPollingPartsValues)
                    {
                        int MeetingPollingPartsValueId = MeetingPollingPartsValue.MeetingPollingPartsValuesId;
                        var MeetingPollingPartsValuesImage = db.MeetingPollingPartsValuesImages.Where(x => x.MeetingPollingPartsValuesId == MeetingPollingPartsValueId).ToList();
                        deleteMeetingPollingPartsValuesImages.AddRange(MeetingPollingPartsValuesImage);
                    }


                    db.MeetingPollingPartsValuesImages.RemoveRange(deleteMeetingPollingPartsValuesImages);
                    db.MeetingPollingPartsValues.RemoveRange(deleteMeetingPollingPartsValues);
                    db.MeetingPollingParts.RemoveRange(deleteMeetingPollingParts);
                    db.MeetingPollingQuestions.Remove(MeetingPollingQuestions);

                    int? positionSequenceOrder = 1;


                    var reorderingmeetingpollingQuestions = db.MeetingPollingQuestions.Where(w=>w.MeetingPollingId == reorderinMeetingPollingId).OrderBy(x=>x.SequenceOrder).ToList();
                    
                    foreach (var updatereorderingQuestion in reorderingmeetingpollingQuestions.Where(w=>w.MeetingPollingQuestionId != MeetingPollingQuestionId))
                    {
                        updatereorderingQuestion.SequenceOrder = positionSequenceOrder;
                        db.Entry(updatereorderingQuestion).State = System.Data.Entity.EntityState.Modified;
                        positionSequenceOrder ++;
                    }


                    db.SaveChanges();
                    dbTran.Commit();
                }

                result.ResultCode = Convert.ToInt32(Enums.Result.Code.Success);
                result.Message = "Successfully uploaded.";
            }
            catch (Exception e)
            {
                dbTran.Rollback();
                result.Message = "Error Save Meeting Polling Question" + e.Message;
                result.ResultCode = Convert.ToInt32(Enums.Result.Code.Error);

            }
            return result;
        }
    }
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Specify the exact version of EF. \$\endgroup\$ Commented Nov 18, 2022 at 20:58
  • \$\begingroup\$ I updated the post with the version \$\endgroup\$
    – Jefferson
    Commented Nov 19, 2022 at 0:33
  • 2
    \$\begingroup\$ As I know, EF4 does not have Database.BeginTransaction method. \$\endgroup\$ Commented Nov 19, 2022 at 9:11
  • \$\begingroup\$ sorry its version 6.0.0.0 \$\endgroup\$
    – Jefferson
    Commented Nov 19, 2022 at 13:05

2 Answers 2

4
\$\begingroup\$

If I understood the relations between your entities correctly, the code can be greatly simplified by making a single query using Include. This method load all related entities.
However, this single sql-query will be very complex, with multiple Joins.

After that, the Remove method will delete the entire hierarchy of objects in the cascade.

using (var db = new NccnEcommerceEntities())
{
    var meetingPollingQuestions = db.MeetingPollingQuestions
        .Include(x => x.MeetingPollingParts.Select(y => y.MeetingPollingPartsValues.Select(z => z.MeetingPollingPartsValuesImages)))
        .FirstOrDefault(x => x.MeetingPollingQuestionId == MeetingPollingQuestionId);

    if (meetingPollingQuestions != null)
    {
        int? reorderinMeetingPollingId = meetingPollingQuestions.MeetingPollingId;

        db.MeetingPollingQuestions.Remove(meetingPollingQuestions);

        int? positionSequenceOrder = 1;

        var reorderingMeetingpollingQuestions = db.MeetingPollingQuestions.Where(w => w.MeetingPollingId == reorderinMeetingPollingId).OrderBy(x => x.SequenceOrder).ToList();

        foreach (var updateReorderingQuestion in reorderingMeetingpollingQuestions.Where(w => w.MeetingPollingQuestionId != MeetingPollingQuestionId))
        {
            updateReorderingQuestion.SequenceOrder = positionSequenceOrder;
            positionSequenceOrder++;
        }

        db.SaveChanges();
    }
}

There is no need to manually set the entity State property. It will be marked as modified by itself.


It is very wasteful to download data from the database only to immediately remove it.
In pure SQL, your task can be solved with a single query directly in the database.
But Entity Framework is not able to generate such an efficient SQL.

You can look for extensions for EF that have Bulk Update and Remove operations. There are such extensions for EF Core.
Also, such amazing features have appeared in the newest EF Core 7 version. I advise you to take a closer look at it.

\$\endgroup\$
2
  • \$\begingroup\$ Is there anything within Ef that will handle the SequenceOrder? \$\endgroup\$
    – Jefferson
    Commented Nov 19, 2022 at 21:34
  • \$\begingroup\$ @Jefferson SequenceOrder can be handled by DBMS side. like using computed column or using triggers. \$\endgroup\$
    – iSR5
    Commented Nov 20, 2022 at 21:12
2
\$\begingroup\$

Quick remarks:

  • reorderinMeetingPollingId is assigned but never used.

  • Why don't you use var in assignments like ResultStatus result = new ResultStatus(); and List<MeetingPollingPartsValue> deleteMeetingPollingPartsValues = new List<MeetingPollingPartsValue>(); etc.?

  • I understand that naming things is hard, but a class name like MeetingPollingPartsValue just baffles me, MeetingPollingPartsValuesImage (why are two parts of that name a plural?).

  • int MeetingPollingPartsId and var MeetingPollingPartsValue etc. don't follow the capitalization guidelines; they should be camelCase. Ditto MeetingPollingQuestionId.

  • Compound words should have each part capitalized. updatereorderingQuestion and reorderingmeetingpollingQuestions do not follow that guideline.

  • Why is there a Where following reorderingmeetingpollingQuestions in the foreach? Why isn't that at the end of the assignment the line above?

  • Do not pointlessly abbreviate, e.g. dbTran.

  • var MeetingPollingQuestions doesn't follow the capitalization guidelines, plus it is a plural name despite it being a single item. This is confusing.

  • Why is the property ResultCode an int? Why not make it an enum, so you won't need to convert your enum to an int?

  • Why don't you simply cast your enum value to an int instead of doing Convert.ToInt32(Enums.Result.Code.Success);?

  • I would advise against consolidating enums in a folder/namespace named Enums. Moreover, why isn't your enum not called ResultCode?

  • If I understand this correctly, you have a folder named "Result": Enums.Result.Code.Success? To me that feels wrong: folders are namespaces and therefor should almost always be plural.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.