0

我有 2 个实体,比如说,旅行和活动。它们之间的关系是多对多的,因此 EF 会自动创建一个连接表。

实体行程属性:
-Id (PK) 由数据库生成
-Name
-Description
-Property1
-Property2
-Property3

实体活动属性(该实体包含固定记录-只读-,执行插入时此处不插入记录):-
Id(PK)由数据库生成
-Name
-Description
-Cost

连接表包含2列,即上述实体的ID,同时是主键和外键。

我插入条目没有问题,这些条目会自动 EF 创建连接表 TripActivities 并成功添加条目。条目也成功添加到实体 Trip 中,并且实体 Activity 保持不变。

例如,我的问题在于更新条目 - 假设用户可以从 GUI 修改与旅行相关的信息 - 所以我从这个 GUI 中获取所有信息,并执行以下步骤来更新现有旅行:

   Trip trip = Context.Trips.Find(id); // Search for the appropriate trip to update from Id

   trip.Name = ObtainNameFromGUI();
   trip.Description = ObtainDescriptionFromGUI();
   trip.Property1 = ObtainProperty1FromGUI();
   trip.Property2 = ObtainProperty2FromGUI();
   trip.Property3 = ObtainProperty3FromGUI();
   trip.Activities = new List<Activity>();

   // From the GUI user selects from a checkbox list the activities associated to the trip
   // So we read its Ids and from those ids we fetch from database the activities to obtain
   // the info related to each activity selected in the GUI. This is all done inside the
   // below method.
   List<Activity> activities = this.ObtainActivitiesSelectedFromGUI();

   // If no activites selected (=null) I want EF automatically deletes the entries in the
   // joined table for this trip. And of course, if there are activities selected, EF 
   // should update the respectives entries in the joined table for this trip with the new
   // ones.
   if (activites != null)
   {
       activities.ForEach(a =>
                    {
                        trip.Activities.Add(a);
                    });
   }

   context.Trips.Add(trip);
   context.SaveChanges();<br><br>

通过这样做,我希望 EF 更新所有相关实体(Activity 除外,因为它具有固定条目,必须保持不变),即 Trip 和连接表自动但它不起作用:创建了一个新的行程,并且有更多的条目连接表(唯一有效的是实体 Activity 保持不变)。

如何做到这一点?我花了很多时间试图做到这一点,但没有成功......

提前致谢。

编辑:
我已删除行:
context.Trips.Add(trip);

现在结果是:
-Entity Trip 已正确更新,没有添加新记录,这很好。
-实体活动保持不变,这没关系。
-加入表:当前行程的旧记录不更新,而是为当前行程插入不正确的新记录。

4

2 回答 2

3

对于我遇到的类似情况,我使用了不同的方法,它适用于分离实体。我最终通过将 GUI(分离实体)值与数据库值进行比较来找出添加了哪些实体以及删除了哪些实体。这是我使用的示例代码。游戏中的实体是RelayConfigStandardContact,它们具有多对多关系

    public void Update(RelayConfig relayConfig, List<StandardContact> exposedContacts) {
        RelayConfig dbRelayConfig = context.RelayConfigs.Include(r => r.StandardContacts)
                                           .Where(r => r.Id == relayConfig.Id).SingleOrDefault();
        context.Entry<RelayConfig> (dbRelayConfig).CurrentValues.SetValues(relayConfig);

        List<StandardContact> addedExposedContacts = 
            exposedContacts.Where(c1 => !dbRelayConfig.StandardContacts.Any(c2 => c1.Id == c2.Id)).ToList();
        List<StandardContact> deletedExposedContacts = 
            dbRelayConfig.StandardContacts.Where(c1 => !exposedContacts.Any(c2 => c2.Id == c1.Id)).ToList();

        StandardContact dbExposedContact = null;
        addedExposedContacts.ForEach(exposedContact => {
            dbExposedContact = context.StandardContacts.SingleOrDefault(sc => sc.Id == exposedContact.Id);
            dbRelayConfig.StandardContacts.Add(dbExposedContact);
        });
        deletedExposedContacts.ForEach(exposedContact => { dbRelayConfig.StandardContacts.Remove(exposedContact);});
于 2013-05-20T16:47:01.597 回答
0

你会使用这样的东西。假设您将从 UI 中获取相关对象,并且您将在数据库中更新相同的对象,则类似以下的操作将起作用。

 context.Products.Attach(product);
            context.ObjectStateManager.ChangeObjectState(product, System.Data.EntityState.Modified);
            context.ObjectStateManager.ChangeObjectState(product.ProductDescription, System.Data.EntityState.Modified);
            context.ObjectStateManager.ChangeObjectState(product.ProductModel, System.Data.EntityState.Modified);
            context.SaveChanges();

正如您在此处看到的那样,我们将 EntityState 设置为 Modified,这会提示 EF 也对相关表执行更新。

请回复您的查询或您在此实施中可能遇到的任何问题。

于 2013-05-20T13:53:44.360 回答