2

I'm having the same problem that a few of you have had - when trying to insert a new object, EF inserts null values for some of their properties, and the insert fails.

First let me describe the structure of our DB. Its an event management system, in which each event needs to be associated with a practice group, stored in a cache table but ultimately fetched from Active Directory. I manually created the join table - is that a problem? Anyway, so Event has a foreign key pointing to EventPracticeGroup, which has a foreign key pointing to PracticeGroupCache. PracticeGroupCache also has a RegionId pointing to the Regions table.

The problem comes when trying to insert a new EventPracticeGroup object. Below is the code I'm currently using:

var eventPracticeGroup = new EventPracticeGroup();
if (TryUpdateModel<EventPracticeGroup>(eventPracticeGroup))
{
    /*
    var eventId = EventScheduleRepository.GetById(Convert.ToInt32(Request.QueryString["EventScheduleId"])).EventId;
    eventPracticeGroup.Event = EventRepository.GetById(eventId);
    eventPracticeGroup.PracticeGroupCache = PracticeGroupCacheRepository.GetById(eventPracticeGroup.PracticeGroupCacheId);
    eventPracticeGroup.PracticeGroupCache.Region = RegionRepository.GetById(eventPracticeGroup.PracticeGroupCache.RegionId);
    EventPracticeGroupRepository.Add(eventPracticeGroup);
    */

    var eventId = EventScheduleRepository.GetById(Convert.ToInt32(Request.QueryString["EventScheduleId"])).EventId;
    var theEvent = new Event() { Id = eventId };
    EventRepository.Repository.UnitOfWork.Context.AttachTo("Events",theEvent);
    var practiceGroupCache = new PracticeGroupCache() { Id = eventPracticeGroup.PracticeGroupCacheId };
    practiceGroupCache.Region = new Region() { Id = eventPracticeGroup.PracticeGroupCache.RegionId };
    eventPracticeGroup.PracticeGroupCache = practiceGroupCache;
    EventPracticeGroupRepository.Add(eventPracticeGroup);
    EventPracticeGroupRepository.Save();
    return RedirectToAction("Index");
}

Anyway... as you can see, I've just tried using stub objects (no help), and I've also tried actually fetching and setting the objects. The error I get is:

Cannot insert the value NULL into column 'Name', table 'XXXX.dbo.Regions'; column does not allow nulls. INSERT fails. The statement has been terminated.

Obviously name is not a key field. I have checked the EDMX XML - only the Id (primary key columns) have StoreGeneratedPattern set to Identity, as they should (they are int32 identity columns). Not a single foreign key has StoreGeneratedPattern set to identity.

if I set Regions.Name to allow nulls, PracticeGroupCaches.Description throws the same error. It seems that every linked object gets set to null. I did have a look with the debugger, when I used the now commented out code, nothing was null and everything had a value. I even got the RegionRepository to return all of the regions, just to see if one of them somewhere had a null name. None did. There are only 2 in my test DB. Our object context is shared per HTTP request.

Please can anyone help. At this point I would settle for using the dirtiest workaround as long as it worked.

Regards, Jonathan.

Dan F
  • 11,958
  • 3
  • 48
  • 72
user846091
  • 21
  • 1
  • 2

3 Answers3

0

Try to Add: [DatabaseGenerated(DatabaseGeneratedOption.None)]

On your Id field, Like:

[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
Refael
  • 6,753
  • 9
  • 35
  • 54
0

Look what happens when you call this line:

EventPracticeGroupRepository.Add(eventPracticeGroup);

You are adding a new eventPracticeGroup to the context. But eventPracticeGroup has the other related objects:

eventPracticeGroup -> PracticeGroupCache -> Region

And you create new objects for those:

var practiceGroupCache = new PracticeGroupCache() {
    Id = eventPracticeGroup.PracticeGroupCacheId };
practiceGroupCache.Region = new Region() {
    Id = eventPracticeGroup.PracticeGroupCache.RegionId };
eventPracticeGroup.PracticeGroupCache = practiceGroupCache;

When you add the eventPracticeGroup to the context this whole object graph gets added which means that EF considers all three objects as new which have to be added to the DB. Since you only fill the Id properties other string properties (like Name or Description) are null. Because they are not nullable in the database the INSERT command fails.

But I guess that you don't want to insert the related entities into the DB anyway but only the eventPracticeGroup. So you need to attach them to the context before you add the new object, something like:

var practiceGroupCache = new PracticeGroupCache() {
    Id = eventPracticeGroup.PracticeGroupCacheId };

EventRepository.Repository.UnitOfWork.Context.AttachTo(
   "PracticeGroupCaches",practiceGroupCache);

practiceGroupCache.Region = new Region() {
    Id = eventPracticeGroup.PracticeGroupCache.RegionId };

EventRepository.Repository.UnitOfWork.Context.AttachTo(
   "Regions",practiceGroupCache.Region);

eventPracticeGroup.PracticeGroupCache = practiceGroupCache;

EventPracticeGroupRepository.Add(eventPracticeGroup);

BTW as a side note: About this EventRepository.Repository.UnitOfWork.Context.XXX take a look at Ladislav Mrnka's answer here: EF 4.0 IsAttachedTo extension method and error An object with the same key already exists

Community
  • 1
  • 1
Slauma
  • 175,098
  • 59
  • 401
  • 420
  • Thanks, some interesting notes there, I'll read through those links. even if I fetched the objects from the repository (ie the context knew they already existed in the data store), it failed with the same reason. the solution, as posted above, turned out to be to set the navigation properties to null and then assign an EntityKey. thanks for the help! – user846091 Jul 18 '11 at 06:54
-1

It seems like you already found the problem and the solution. In your DB schema it seems like the columns don't allow NULL values. So either change all these columns to allow NULL or don't insert null (this is what you currently are trying to do)

Fabiano
  • 5,124
  • 6
  • 42
  • 69
  • I did - the solution was found here: http://stackoverflow.com/questions/2550231/mvc-2-entity-framework-view-model-insert . I wasnt trying to insert a null, thats the point. – user846091 Jul 18 '11 at 06:52