Entity framework MVC 3 EF 4.1 dbContext-删除具有不可空外键关系的一对多数据对象
我使用的是MVC3、EF4.1和dbContext。我需要知道如何删除与不可空外键存在一对多关系的实体 当我删除子实体并执行SaveChanges时,会出现以下错误: 操作失败:无法更改关系,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象 从其他帖子中,我了解到使用Remove(entity)将实体标记为delete。在SaveChanges期间,EF将外键设置为Null,并出现上述错误 我发现一些帖子在子实体上使用DeleteObject而不是Remove;然而,由于添加了dbContext和DbSet,DeleteObject方法似乎已被放弃 我发现有帖子建议将EDMX外键关系修改为可空。修改EDMX是可以的,但每当数据库的更新模型完成时,这些更改都会被取消,必须重新应用。不是最优的 另一篇帖子建议创建一个外键关系设置为Nullable的代理实体,但我不理解这种方法。它似乎遇到了与修改EDMX相同的问题,即当保存对EDMX的更改时,上下文会自动更新 我的简化模型是:Entity framework MVC 3 EF 4.1 dbContext-删除具有不可空外键关系的一对多数据对象,entity-framework,asp.net-mvc-3,Entity Framework,Asp.net Mvc 3,我使用的是MVC3、EF4.1和dbContext。我需要知道如何删除与不可空外键存在一对多关系的实体 当我删除子实体并执行SaveChanges时,会出现以下错误: 操作失败:无法更改关系,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象 从其他帖子中,我了解到使用Remove(entity)将实体标记为delete。在SaveChanges期间,EF将外键设置为Nu
public partial class User
{
public User()
{
this.UserContacts = new HashSet<UserContact>();
}
public long userId { get; set; }
public string userEmail { get; set; }
public string userPassword { get; set; }
public string userFirstName { get; set; }
public string userLastName { get; set; }
. . .
public virtual Country Country { get; set; }
public virtual State State { get; set; }
public virtual ICollection<UserContact> UserContacts { get; set; }
}
userContactUserId和userContactTypeId是必需的外键
在dbContext容器中,用户和用户联系人都是DbSet
我有一个用于用户的ViewModel和一个用于UserContact的ViewModel,如下所示
public class UserContactViewModel
{
[HiddenInput]
public long UserContactId { get; set; }
[HiddenInput]
public long UserContactUserId { get; set; }
[Display(Name = "Contact")]
[Required]
public string ContactData { get; set; }
[Required]
public long ContactType { get; set; }
[HiddenInput]
public bool isDeleted { get; set; }
}
public class MyProfileViewModel
{
[HiddenInput]
public long UserId { get; set; }
[Required]
[Display(Name = "First Name")]
[StringLength(100)]
public string FirstName { get; set; }
[Required]
[StringLength(100)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
....
public IEnumerable<UserContactViewModel> Contacts { get; set; }
}
非常感谢您的帮助。您可以将关系配置为级联。。。这将把删除传播到依赖实体 但这非常危险:)
我更喜欢在行中设置一个标志,以防止数据层在将来的查询中包含它,大多数应用程序不需要物理删除(并且将有机会撤消)。好的,实现您自己的ICollection,并在删除这些子对象的同时将其标记为删除。然后,在您自己的SaveChanges方法覆盖中,删除这些对象。我在MSDN指南页面的“关系级联删除规则”一节中解决了相同的问题
希望你能有所帮助:D我设法解决了这个问题,如下所示: 首先,我能够通过将DbContext(例如“ctx”)强制转换为IObjectContextAdapter,然后获取对ObjectContext的引用来获取ObjectContext 接下来,我简单地调用DeleteObject方法来传递要删除的UserContact记录 当SaveChanges获得时,数据库中的删除将按预期进行
if (c.isDeleted == true) // Deleted UserContact
{
ObjectContext oc = ((IObjectContextAdapter)ctx).ObjectContext;
oc.DeleteObject(uc)
}
以下是相关代码的片段:
foreach (var c in model.Contacts)
{
UserContact uc = null;
if (c.UserContactId != 0)
{
uc = ctx.UserContacts.Find(c.UserContactId);
}
if (uc != null)
{
if (c.isDeleted == true) // Deleted UserContact
{
ObjectContext oc = ((IObjectContextAdapter)ctx).ObjectContext;
oc.DeleteObject(uc);
}
else // Modified UserContact
{
uc.userContactData = c.ContactData;
uc.userContactTypeId = c.ContactType;
ctx.Entry(uc).State = EntityState.Modified;
}
}
else // New UserContact
{
usr.UserContacts.Add(new UserContact { userContactData = c.ContactData, userContactTypeId = c.ContactType });
}
}
ctx.Entry(usr).State = EntityState.Modified;
ctx.SaveChanges();
希望这对将来的人有所帮助。你有没有找到解决办法?我也有同样的问题,你找到解决办法了吗?我也有同样的问题?@BZ你找到解决办法了吗?我也有同样的问题?我确实找到了解决办法,请参阅下面我的回答帖子。
if (c.isDeleted == true) // Deleted UserContact
{
ObjectContext oc = ((IObjectContextAdapter)ctx).ObjectContext;
oc.DeleteObject(uc)
}
foreach (var c in model.Contacts)
{
UserContact uc = null;
if (c.UserContactId != 0)
{
uc = ctx.UserContacts.Find(c.UserContactId);
}
if (uc != null)
{
if (c.isDeleted == true) // Deleted UserContact
{
ObjectContext oc = ((IObjectContextAdapter)ctx).ObjectContext;
oc.DeleteObject(uc);
}
else // Modified UserContact
{
uc.userContactData = c.ContactData;
uc.userContactTypeId = c.ContactType;
ctx.Entry(uc).State = EntityState.Modified;
}
}
else // New UserContact
{
usr.UserContacts.Add(new UserContact { userContactData = c.ContactData, userContactTypeId = c.ContactType });
}
}
ctx.Entry(usr).State = EntityState.Modified;
ctx.SaveChanges();