我正在制作代码第一个实体框架数据库模型,而且我正在使用级联删除。我有简单的课程:
public class User {
[Key()]
public int Id {get; set;}
public string Name {get; set;}
public int CampaignId {get; set;}
[ForeignKey("CampaignId")]
public virtual Campaign Campaign {get; set;}
}
public class Campaign {
[Key()]
public int Id {get; set;}
public string Description {get; set;}
public virtual List<User> Users {get; set;}
public Campaign() {
Users = new List<User>();
}
}
基本思路是为每个用户分配一个广告系列。当我删除用户指定的广告系列时:
internal static void DeleteCampaign(Campaign campaignToDelete) {
using (var context = new DatabaseContext()) {
context.Entry(campaignToDelete).State = EntityState.Deleted;
context.SaveChanges();
}
}
分配给该广告系列的用户也会被删除。我想要的是不删除用户,但将其分配给第一个可用的广告系列,或为null。出于某种原因,我不能做那样的事情:
internal static void DeleteCampaign(Campaign campaignToDelete) {
using (var context = new DatabaseContext()) {
for (int i = 0; i < campaignToDelete.Users.Count; i++) {
campaignToDelete.Users[i].Campaign = context.Campaigns.ElementAt(0);
}
context.Entry(campaignToDelete).State = System.Data.Entity.EntityState.Deleted;
context.SaveChanges();
}
}
因为我收到错误:
An unhandled exception of type 'System.ObjectDisposedException' occurred in EntityFramework.dll
Additional information: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
那我怎么能避免呢?
答案 0 :(得分:0)
使用虚拟时,默认情况下应启用延迟加载。
这可能会有所帮助: How to disable cascade delete for link tables in EF code-first?
答案 1 :(得分:0)
1)您将哪种对象传递给 DeleteCampaign 方法? 我认为这是你的实体框架代理模型之一,它被另一个数据库上下文查询。 您可以在for循环中访问链接的 User 对象,由于上下文不再存在,因此无法加载该对象。
for (int i = 0; i < campaignToDelete.Users.Count; i++) {
不要混合使用不同数据库上下文的对象。
更好的方法是,您将广告系列的ID传递给 DeleteCampaign 方法,然后您必须在新数据库上下文中查询广告系列。 之后,您可以在一个using语句(=相同的数据库上下文)中执行所有操作。
static void DeleteCampaign(int idOfCampaignToDelete)
{
using (var context = new DatabaseContext())
{
var campaignToDelete = context.Campaigns.FirstOrDefault(c => c.Id == idOfCampaignToDelete);
for (int i = 0; i < campaignToDelete.Users.Count; i++)
{
campaignToDelete.Users[i].Campaign = context.Campaigns.ElementAt(0);
}
context.Entry(campaignToDelete).State = System.Data.Entity.EntityState.Deleted;
context.SaveChanges();
}
}
2)您不能在LINQ to Entities查询中使用ElementAt(0)。 使用.FirstOrDefault()。
campaignToDelete.Users[i].Campaign = context.Campaign.FirstOrDefault();
3)使您的User类中的CampaignId可为空。否则,您不能拥有没有广告系列的用户,因为外键不可为空。
public int? CampaignId {get; set;}
现在你的代码应该可行了。