Adding & Updating Foreign key in Entity Framework v1

entity-framework foreign-keys

Question

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
3
8/12/2009 6:30:10 AM

Accepted Answer

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

8
8/12/2009 7:47:02 AM

Popular Answer

UPDATE: see Craig Stuntz' and Alex James' comments - I stand corrected - it appears to be possible to simply update the "EntityKey" in order to achieve what you asked for. My post here doesn't apply anymore

In version 1, Entity Framework can't work with just foreign key values being inserted - you'll need to add the "Category" object instance to the "AppUser"'s Cateogry navigation property:

//create entity with passed values
AppUser user = new AppUser(){Uid=id, ....  }

// set the Category navigation property
Category newUserCategory  = Category.GetbyID(4); // or whatever you need
user.Category = newUserCategory;

myContext.AddToCategorySet(user);
myContext.SaveChanges(true);

With EF v4 which will ship with .NET 4.0 some time later this year (2009), you will then be able to set just the foreign key value to make associations between two entities happen.

See more info on that here:

But for now, you need to set the full object - just the reference won't do.

Marc



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow