4

My Simplified database:

   +----------+
   |Products  |
   +----------+
   |ProductID |
   |ProdName  |
   |Desc      |
   |BrandID   |
   |CategoryID|
   +----------+

   +----------+
   |Brands    |
   +----------+
   |BrandID   |
   |BrandName |
   |ImageID   |
   |Desc      |
   +----------+

   +----------+
   |Categories|
   +----------+
   |CategoryID|
   |CategName |
   |ImageID   |
   |Desc      |
   +----------+

   +----------+
   |Images    |
   +----------+
   |ImageID   |
   |Path      |
   +----------+

   +----------+
   |ImageLinks|
   +----------+
   |ImageID   |
   |ProductID |
   +----------+

(Note: A product can have multiple images, but a brand/category can have at most one)

In ASP.NET,

   using (DBEntities db = new DBEntities()) 
   {
         Product product = db.Products.FirstOrDefault(p => p.ProductID == 1);
         if (product != null) product.Desc = "any value";
         db.SaveChanges(); //works


         Image image = db.Images.FirstOrDefault(i => i.ImageID == 1);
         if (image != null) image.Path = "any value";
         db.SaveChanges(); //works

         Brand brand = db.Brands.FirstOrDefault(b => b.BrandID == 1);
         if (brand != null) brand.Desc = "the same value as the old description";
         db.SaveChanges();  //works

         Brand brand = db.Brands.FirstOrDefault(b => b.BrandID == 1);
         if (brand != null) brand.Desc = "some new description";
         db.SaveChanges();  //throws null reference exception

         Category categ = db.Categories.FirstOrDefault(c => c.CategoryID == 1);
         if (categ != null) categ.Desc = "the same value as the old description";
         db.SaveChanges();  //works

         Category categ = db.Categories.FirstOrDefault(c => c.CategoryID == 1);
         if (categ != null) categ.Desc = "some new description";
         db.SaveChanges();  //throws null reference exception
   }

This is very weird!

Here is the stack trace of the NullReferenceException being thrown by SaveChanges()

Object reference not set to an instance of an object.
   at System.Web.UI.ParseChildrenAttribute.GetHashCode()
   at System.Collections.Generic.ObjectEqualityComparer`1.GetHashCode(T obj)
   at System.Collections.Generic.HashSet`1.InternalGetHashCode(T item)
   at System.Collections.Generic.HashSet`1.AddIfNotPresent(T value)
   at System.Collections.Generic.HashSet`1.UnionWith(IEnumerable`1 other)
   at System.Collections.Generic.HashSet`1..ctor(IEnumerable`1 collection, IEqualityComparer`1 comparer)
   at System.Collections.Generic.HashSet`1..ctor(IEnumerable`1 collection)
   at System.Data.Entity.ModelConfiguration.Utilities.AttributeProvider.GetAttributes(Type type)
   at System.Data.Entity.ModelConfiguration.Utilities.AttributeProvider.GetAttributes(PropertyInfo propertyInfo)
   at System.Data.Entity.Internal.Validation.EntityValidatorBuilder.BuildPropertyValidator(PropertyInfo clrProperty)
   at System.Data.Entity.Internal.Validation.EntityValidatorBuilder.BuildValidatorsForProperties(IEnumerable`1 clrProperties, IEnumerable`1 edmProperties, IEnumerable`1 navigationProperties)
   at System.Data.Entity.Internal.Validation.EntityValidatorBuilder.BuildTypeValidator[T](Type clrType, IEnumerable`1 edmProperties, IEnumerable`1 navigationProperties, Func`3 validatorFactoryFunc)
   at System.Data.Entity.Internal.Validation.EntityValidatorBuilder.BuildEntityValidator(InternalEntityEntry entityEntry)
   at System.Data.Entity.Internal.Validation.ValidationProvider.GetEntityValidator(InternalEntityEntry entityEntry)
   at System.Data.Entity.Internal.InternalEntityEntry.GetValidationResult(IDictionary`2 items)
   at System.Data.Entity.DbContext.ValidateEntity(DbEntityEntry entityEntry, IDictionary`2 items)
   at System.Data.Entity.DbContext.GetValidationErrors()
   at System.Data.Entity.Internal.InternalContext.SaveChanges()
   at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
   at System.Data.Entity.DbContext.SaveChanges()
   at VatechWebsite.Admin.Image_Upload.UploadBtn_Click(Object sender, EventArgs e) in c:\Users\Toshiba User\Desktop\vatech\VatechWebsite\VatechWebsite\Admin\Image_Upload.aspx.cs:line 109

PS: this is entity framework 5

Karim
  • 247
  • 4
  • 11
  • You can just call `SaveChanges` once at the end of that method... – Mansfield Oct 27 '13 at 02:01
  • I tried that too, it didn't work... – Karim Oct 27 '13 at 02:21
  • The stack trace shows that the exception is coming from the validation that happens inside SaveChanges. This validation is by default based on DataAnnotation attributes, and apparently in your case there is some interaction with some attribute from System.Web. Perhaps a bug in some attribute code you have in the entity classes or their properties? Worst case you can disable validation on saves, but it would be interesting to take a look at your entity types. – divega Oct 27 '13 at 04:37
  • That's interesting.. Disabling validation on saves works, but I'm not sure what kind of bug I might have in the entity classes.. I am using Database first and relying on EF to generate this code. All my non-ID columns are nullable so I'm not sure what could be the problem – Karim Oct 27 '13 at 11:42
  • It is interesting indeed. I had not seen this happen before, but I did a search just now and I found this previous thread: http://stackoverflow.com/questions/17136455/nullreferenceexception-in-dbcontext-savechanges. Could you please confirm that this solve the issue? – divega Oct 28 '13 at 17:28
  • It did solve it :) :D The funny thing is that I looked at that post before asking my question but automatically or subconsciously ruled out the case that I have a class with the same name! How stupid :/ Thanks for making me look again! – Karim Oct 28 '13 at 22:02

2 Answers2

2

As divega pointed out, the problem was that I had a class with the same name as the entity generated by EF (both for Category and Brand). Refer to this post NullReferenceException in DbContext.saveChanges()

Community
  • 1
  • 1
Karim
  • 247
  • 4
  • 11
0

I think the way you are assigning the entity model's object class is not proper. Apply the following change to all the entity objects in your code and then try:

Product product = db.Products.FirstOrDefault(p => p.ProductID == 1); /* for products */

And do likewise for the Categories, Images and brands also.

All the best.

Girish Vadhel
  • 735
  • 1
  • 5
  • 17
  • Sorry about that, this is what I'm doing in the real case but I copied the code wrong. I'll update my question – Karim Oct 27 '13 at 11:13