views:

2610

answers:

4

Hello,

I'm using .NET 3.5 SP1. I created entity 'Category', based on table 'category_table' and 'MyUser', based on table 'App_User_table'.

CREATE TABLE category_table (
 catg_id int,
 catg_name varchar(50),
 catg_description varchar(250)
 )

CREATE TABLE App_User_table (
 userid int,
 username varchar(50),
 fullname varchar(50), catg_id int,
 fullAddress varchar(200),
 comments varchar(1000),CONSTRAINT FK_1 FOREIGN KEY (catg_id) REFERENCES Category_table (catg_id) 
)

public class Category: System.Data.Objects.DataClasses.EntityObject{    
 public int  CategoryId{get; set;}   
 public string CategoryName {get; set;} 
  ....
}

public class AppUser : System.Data.Objects.DataClasses.EntityObject{   
 public int Uid {get; set;}   
 public string UserName {get; set;}   
 public string Name {get; set;}   
 public string Address {get; set;}
 public string Comment {get; set;} 
 public Category category_table  { .. } 
 public System.Data.Objects.DataClasses.EntityReference<Category> category_tableReference {...}
 ...........   
}


I want to add and update AppUser entity in an ASP.NET MVC application.

For Add:

//create entity with passed values
AppUser user = new AppUser(){Uid=id, ....  }
//Set EntityReference
user.category_tableReference.EntityKey = new System.Data.EntityKey("MyContext.CategorySet", "CategoryId", categoryIdSelected);
myContext.AddToCategorySet(user);
myContext.SaveChanges(true);

For Update:

//create entity with passed Id 
AppUser user = new AppUser(){Uid=id  }
//Attach entitymyContext.AttachTo("UserSet", user);
//Update entity with passed values
user.Address = addr;
....

//update selected CategoryId from DropDownList

user.category_tableReference.EntityKey = new System.Data.EntityKey("MyContext.CategorySet", "CategoryId", categoryId);

Update method does NOT update CategoryId in database.

Please tell, what is the best way to resolve the issue ?

Thank you.

+1  A: 
marc_s
That's just not true. Aside from Alex's "stub object" suggestion, you can also new up an EntityKey with just the ID and assign that to the reference.
Craig Stuntz
Well, Alex's suggestion is basically the same as mine - you just need to create a "full" Category object - you can't just assign the value "4" to a foreign key column - you need to supply a "Category" object.
marc_s
Can you show us all how to assign that EntityKey?
marc_s
Alex's suggestion involved no DB reads. Your suggestion involves DB reads. That's different IMHO. To assign the EntityKey, you would do something like (guessing at names) user.CategoryReference.EntityKey = new EntityKey("MyEntities.Categories", "Cid", 4);
Craig Stuntz
@Craig: sure, I agree - Alex's suggestion is slicker, but the fact remains - you have to supply a full "Category" object. I'll try your EntityKey approach - I wasn't aware this works in EFv1 - I'll give it a try!
marc_s
It seems the OP used that EntityKey line more or less 1:1 as you wrote it, and he says it doesn't work - doesn't update his entity.
marc_s
You can of course use the EntityKey approach too. The only thing is for Update you need to specify the Original EntityKey too before you change it to the latest value. In 3.5 relationships (i.e. PK-FK pairs) are part of concurrency checks, so in order to change one end (i.e. the FK) you need to provide the original FK value, so the ef can delete the original PK-FK pair and insert the new PK-FK pair. As you know with FK associations this changes. Primarily because the FK is now structurally part of the Entity, which means you no longer need the original value to update it.
Alex James
OK, thanks Alex! I'll update my post. You learn something every single day! :)
marc_s
+5  A: 

Here is the approach I would use for Update in an MVC app:

// Put the original Stub Entities for both the original User and its 
// original category. The second part is vital, because EF needs to know 
// original FK values to successfully do updates in 3.5 SP1
AppUser user = new AppUser {
    Uid = id, 
    Category = new Category {
        CategoryId = OriginalCategoryID
    }
};
ctx.AttachTo("UserSet", user);

// Then do this:
if (user.Category.CategoryId != categoryIdSelected)
{
    Category newCategory = new Category {CategoryId = CategoryIdSelected};
    // Attach because I assume the category already exists in the database
    ctx.AttachTo("CategorySet", newCategory);
    user.Category = newCategory;
}

// Update entity with passed values
user.Address = addr;
....

As you can see you need to be able to get OriginalCategoryID from somewhere, I recommend a hidden field on the form.

This will do the everything you need. Check out Tip 26 - How to avoid database queries using Stub Entities for more info on the Stub Entity trick.

Hope this helps

Alex

Alex James
A: 

Thank you all for your replies/comments.

@Alex: Thanks for efficient solution.

dev
A: 

Hello,

For Add, using Entity stubs:

//create entity with passed values
AppUser user = new AppUser(){Uid=id, ....  }
//Create Category & attach to context 
Category category = new Category(){CategoryId= categoryIdSelected}; 
myContext.AttachTo("CategorySet", category); //After this category EntityState=Unchanged 

user.Category=category; //After this, 'user' EntityState=Added 

myContext.AddToUserSet(user);   //So is this required ?

myContext.SaveChanges(true);

In above case, when attached category is assigned to 'user' entity, user entity gets attached to context, with EntityState=Added.

(EF rule: Whole graph will be in or out of context)

So in this case, is 'myContext.AddToUserSet(user)' statement required ?

Thank you.

dev