简体   繁体   English

如何使用实体框架 6 更新相关数据

[英]How to update related data using entity framework 6

I have an entity Person , which has a related entity Hobby .我有一个实体Person ,它有一个相关的实体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.我想创建一个ViewModel ,允许添加新的爱好和/或从给定的 Person 实体中删除现有的爱好。

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.该消息表示您不能在 LINQ-to-Entities 查询中使用vm.Hobbies ,只能使用原始类型。 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:为了避免这种异常,您可以首先从vm.Hobbies集合中选择 Id,然后过滤您需要的爱好:

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你有一个动作来添加一个新的Hobby将一个Hobby实体作为动作的一部分传回
  • You simply make a call back to the database to create the new association between the Person and Hobby您只需调用回数据库即可创建PersonHobby之间的新关联
  • Add the Hobby entity to the collection in PersonHobby实体添加到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.一般来说,当您尝试与作为整个实体的实体进行交互并且不尝试对自己的 ID、实体水化等事物进行微观管理时,EF 和 MVC 更容易使用。

You could join by ID instead of fetching data from the DB:您可以通过 ID 加入而不是从数据库中获取数据:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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