1

I am using Entity Framework 4.1 code first.

Here is my Category class:

public class Category
{
     public int Id { get; set; }
     public string Name { get; set; }
     public bool IsActive { get; set; }
     public int? ParentCategoryId { get; set; }
     public virtual Category ParentCategory { get; set; }
     public virtual ICollection<Category> ChildCategories { get; set; }
}

The above class is a self-referencing category, for example, a parent category can have a list of child categories.

I want to create a string value of the parent category name and the child category name, for example, Parent Category 1 > Child Category 1-1.

So I get a list of all the parent categories, loop through each parent category. And for each parent category I want to loop through the child category list and combine each child category's name to the parent category's name, so that I have something like:

Animal > Lion
Anumal > Baboon
Anumal > Zebra
etc etc etc...

Here is my looping code. If anyone can help me reduce the lines of code then I would appreciate it :)

public IEnumerable<Category> GetParentChildCategories()
{
     IEnumerable<Category> parentCategoryList = GetParentCategories()
          .Where(x => x.IsActive);
     List<Category> parentChildCategoryList = new List<Category>();

     foreach (Category parentCategory in parentCategoryList)
     {
          foreach (Category childCategory in parentCategory.ChildCategories)
          {
               if (childCategory.IsActive)
               {
                    Category category = new Category
                    {
                         Id = childCategory.Id,
                         Name = parentCategory.Name + " > " + childCategory.Name
                    };
                    parentChildCategoryList.Add(category);
               }
          }
     }

     return parentChildCategoryList;
}

It bombs out in the 2nd foreach when wanting to loop through the child categories. Why is is this? Here is the error:

There is already an open DataReader associated with this Command which must be closed first.

tugberk
  • 57,477
  • 67
  • 243
  • 335
Brendan Vogt
  • 25,678
  • 37
  • 146
  • 234
  • 1
    Here is explained why it throws exception: http://stackoverflow.com/questions/4867602/entity-framework-there-is-already-an-open-datareader-associated-with-this-comman/4868569#4868569 – Ladislav Mrnka Oct 05 '11 at 07:26

3 Answers3

3

EF opens a reader when you iterate parentCategoryList. Then again when you try to iterate parentCategory.ChildCategories EF will open a Reader. Since there is open reader it will throw an error.

What you should do is eager load the ChildCategories. This way EF does not have to open a reader again.

So inside your GetParentCategories() method, use Include to eager load them

return db.Categories.Include(c => c.ChildCategories).Where(/* */);
Eranga
  • 32,181
  • 5
  • 97
  • 96
  • @Brendan Its in `System.Data.Entity` namespace. You have to add reference to `EntityFramework.dll`. But if you are using the `ObjectContext` API you can use `Include("ChildCategories")` – Eranga Oct 05 '11 at 11:07
1

add

MultipleActiveResultSets=True

in the connection string

Rafay
  • 30,950
  • 5
  • 68
  • 101
0

If you just want the combination to be Parent->Child (Category Name) why not return it through a property and no need for that heavy work

Do a partial class for the Category class then write the following property

public string MeAndMyParentCategory
{
   get
   {
      //I assuming that your 
      // (Child's relation with the parent category called [Parent])
      if(this.Parent != null)
         return string.Format("{0} > {1}", Parent.Name, this.Name);
      return string.Empty
   }
}
Rami Alshareef
  • 7,015
  • 12
  • 47
  • 75