views:

86

answers:

3

Hello,

I'm using .NET 3.5 SP1. Using VS2008 Designer, I created entity 'Category' based on table 'Category' and 'AppUser' based on table 'AppUser' and 'AppUserDetail' based on table 'AppUserDetail'.

DB TABLES:
CREATE TABLE  [Category](
    [CategoryId] [int] NOT NULL,
    [CategoryName] [varchar](50) NOT NULL,
    PRIMARY KEY ([CategoryId])
) 
CREATE TABLE  [AppUser](
    [UserId] [int] NOT NULL,
    [UserName] [varchar](50) NOT NULL,
    [CategoryId] [int] NOT NULL, 
    PRIMARY KEY ([UserId]),
    FOREIGN KEY (CategoryId) REFERENCES Category(CategoryId) ON DELETE CASCADE
) 
CREATE TABLE AppUserDetail ( 
    DetailId   int  NOT NULL, 
    UserId  int  not null, 
    Address   varchar(2000) not null,
    Comments   varchar(2000) not null, 
    PRIMARY KEY ([DetailId] ),
    FOREIGN KEY (UserId) REFERENCES AppUser(UserId) ON DELETE CASCADE
)
TABLE RECORDS:
Category:   1, Category-1
AppUser:    1, User1, 1
AppUserDetail:  1, 1, Address-1, Comments-1

Using following code,I retrieve a user and then try to detach all entities in context.

using (var context = new MyEntities()) {
    AppUser user = context.AppUserSet.Where(u => u.UserId == 1).FirstOrDefault();

    //Detach ALL entities
    foreach (var stateEntry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged)) {            
        if (!stateEntry.IsRelationship)
     context.Detach(stateEntry.Entity);
    }
}

I'm getting the following exception:

"System.InvalidOperationException was unhandled
  Message="The object is in a detached state. This operation cannot be performed on an ObjectStateEntry when the object is detached."
  Source="System.Data.Entity"
  StackTrace:
       at System.Data.Objects.ObjectStateEntry.get_IsRelationship()

In code I'm only selecting entities which are not Detached.

Please tell what is cause of this error ?

Thank you.

+1  A: 

Why do you want to detach all entities?

Maybe you can try to use the Context.MergeOption property to retrieve a list of detached entities directly so you don't need to detach them.

See: http://msdn.microsoft.com/en-us/library/system.data.objects.mergeoption.aspx

Davide

Davide Icardi
MergeOption is on ObjectQuery, not ObjectContext. But +1 anyway for a better solution than Detaching.
Craig Stuntz
A: 

I hesitate to ask why you're doing this, but:

When you Detach an entity, the entire graph of related entities is detached. So later in your loop you go to Detach one of those related entities and it's already been detached implicitly by an earlier iteration.

Craig Stuntz
Thanks. But MSDN (http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.detach.aspx) says "Only the entity is removed; if there are any related objects that are being tracked by the same ObjectStateManager, those will not be detached automatically"
dev
I presumed it worked the same as Attach, which certainly behaves as I describe. But you're right; that's what the docs say. Test this and see who is right. It would account for the behavior you're seeing.
Craig Stuntz
A: 

My guess, and it is just a guess, is that deleted items are detached too? It might be worth testing.

Could you change your code so you ignore deleted items?

i.e:

foreach (var stateEntry in context.ObjectStateManager.GetObjectStateEntries(
     EntityState.Added | EntityState.Modified | EntityState.Unchanged
)) {                    
   if (!stateEntry.IsRelationship)        
       context.Detach(stateEntry.Entity);    
}

Alex

Alex James