简体   繁体   中英

How to update related data using entity framework 6

I have an entity Person , which has a related entity Hobby . This is a many to many relationship where a person can have several hobbies, and a hobby can be associated with many people. I want to create a ViewModel that allows new hobbies to be added and/or existing hobbies to be removed from a given Person entity.

The code below works, but I imagine it is rather inefficient.

var newHobbies = new List<Hobby>();

foreach (Hobby hobby in vm.Hobbies)
{
    var originalHobby = db.Hobbies.Find(hobby.HobbyID);
    newHobbies.Add(originalHobby);
}

originalPerson.Hobbies = newHobbies;

I prefer to do something like this:

var newHobbies = db.Hobbies.Where(x => vm.Hobbies.All(y => x.HobbyID == y.HobbyID)).ToList();   
originalPerson.Hobbies = newHobbies;

But I get an error:

Only primitive types or enumeration types are supported in this context.

How can I update related data without going to the database multiple times?

The message says that you can't use vm.Hobbies inside a LINQ-to-Entities query, only primitive types. This is what you can do:

var hobbyIds = vm.Hobbies.Select(h => h.HobbyId).ToList();
var newHobbies = db.Hobbies.Where(x => hobbyIds.Contains(x.HobbyID)).ToList();

To avoid that exception you can select first the Ids from the vm.Hobbies collection and after that filter the hobbies you need:

var Ids=vm.Hobbies.Select(x=>x.HobbyID);

var newHobbies = db.Hobbies.Where(x => Ids.Contains(x.HobbyID)).ToList();
// another option could be: db.Hobbies.Where(x => Ids.Any(id=>id==x.HobbyID)).ToList();    
originalPerson.Hobbies = newHobbies;

The overall construction would be like such:

  • Your view takes the view model which displays the list of hobbies
  • You have an action to add a new Hobby passing a Hobby entity back as part of the action
  • You simply make a call back to the database to create the new association between the Person and Hobby
  • Add the Hobby entity to the collection in Person
  • Return passing the view model back to the view

In general EF and MVC are much easier to work with when you try to interact with your entities as whole entities and don't try to micromanage yourself things such as IDs, entity hydration, and so on.

You could join by ID instead of fetching data from the DB:

originalPerson.Hobbies = db.Hobbies.Join(vm.Hobbies, h => h.ID, 
    v => v.HobbyID, (h, v) => h).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM