2

Let's say I have two classes, a Company class and a Customer class.

public class Company
{
    public int Id {get; set;}
    public Customer Customer {get; set;}
}

public class Customer
{
    public int Id {get; set;}
    public string Name {get; set;}
}

I want to be able to update the customer associated with the company using a drop down list. So, the edit method in my controller creates a viewmodel.

public class ViewModel
{
    public List<Customer> AvailableCustomers {get; set;}

    public Company Company {get; set;}
}

The view creates a form with a drop down list from which to select a customer (using Knockout).

<select data-bind="attr: {name: 'Company.Customer.Id'}, options: AvailableCustomers(), optionsText: 'Name', optionsValue: 'Id', value: Company.Customer.Id"></select>

When the form is posted back to the server, I have the Company model with the new Customer Id selected by the user. Now I want to update the database using Entity Framework.

I get the Company being updated out of the database using the id for the Company that was posted back in the form data, which is just my viewmodel from earlier. Now I want to update the Company with a new Customer. The only information I have at this point is the Id of the Company that the user selected from the drop down list. So I do something like this:

var companyBeingUpdated = repository.GetByKey<Company>(Company.Id);
companyBeingUpdated.Customer.Id = Company.Customer.Id;

As soon as I call update on my repository, I get an exception that says "The property 'Id' is part of the object's key information and cannot be modified". The update method on my repository looks like this:

    public void Update<TEntity>(TEntity entity) where TEntity : class
    {
        var entry = this._dbContext.Entry(entity);

        if (entry.State == EntityState.Detached)
        {
            this._dbContext.Set<TEntity>().Attach(entity);
        }

        entry.State = EntityState.Modified;
    }

I am clearly doing something wrong with Entity Framework. I could easily do this with a SQL statement, but I want to understand what I am doing wrong with EF.

How do I go about updating the Customer related entity of the Company object with EF when the only information I have is the Customer Id posted back in the form data?

I know I could probably retrieve the Customer entity from the database using the Id and assign the Company.Customer to that retrieved Customer, but this is actually a very simplified example. In reality, I have quite a bit more than just one related entity and if I have to make a trip to the database to look up each related entity in order to do the update, I can see performance quickly becoming a problem.

1 Answer 1

1

What you want to do with your entities is have access to the Foreign Key. however, you cannot directly access the Foreign Key through the related entity, instead you are accessing the Primary Key of that related entity.

i.e. instead of accessing the Company Customer_Id property in SQL, you are accessing the Customer Id property.

You can expose the Foreign Keys to your model in Entity Framework, allowing you to do the types of updates you are after.

public class Company
{
    public int Id {get; set;}

    [ForeignKey("CustomerId")]
    public Customer Customer {get; set;}
    public int CustomerId {get;set;}
}

now, you can do updates as companyBeingUpdated.CustomerId = Company.CustomerId; and not have to do a lookup to retrieve the full Customer Entity.

Sign up to request clarification or add additional context in comments.

1 Comment

Well duh. I feel pretty dumb now. It seems obvious now that you have explained it. Thanks for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.