我有两个实体,比方说,旅行和活动。它们之间的关系是多对多的,所以EF会自动创建一个连接表。< br >
实体行程属性: -
ID (PK) 由数据库生成 -名称 -描述 -属性 1 -属性
2
-属性 3
实体活动属性(此实体包含固定记录-read only-,在执行插入时不会在此处插入任何记录):
-Id(PK)由数据库生成
-名称
-描述
-成本
连接表包含 2 列,即上述实体的 ID,它们同时是主键和外键。
我在插入条目时没有任何问题,EF会自动创建join table TripActivities并成功添加条目。此外,条目成功添加到实体行程中,实体活动保持不变。< br>
例如,我的问题是更新条目-假设用户可以从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和连接的表会自动更新,但这不起作用:创建了一个新的Trip,连接的表中有更多的条目(唯一起作用的是实体Activity保持不变,如我所愿)。< br>
如何实现这一点?我花了很多时间试图做到这一点,但没有成功…
提前谢谢
编辑:
我已经删除了行:
conttext. Trips.Add(旅行);
现在结果是:< br >-实体行程被正确更新,没有添加新记录,这是可以的。< br >-实体活动保持不变,这是可以的。< br >-连接表:不更新正在更新的当前行程的旧记录,而是为不正确的当前行程插入新记录。< br >
对于我所面临的类似场景,我使用了一种不同的方法,这种方法在分离的实体上工作得很好。我最终通过比较GUI(分离的实体)值和数据库值来找出哪些实体被添加,哪些被删除。这是我用过的样本代码。起作用的实体是RelayConfig和StandardContact,它们具有多对多关系
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);});
您将使用这样的东西。假设您将从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也要对相关表执行更新。
请将您的疑问或在实施过程中可能遇到的任何问题发送回来。