实体框架 – MVC 3 EF 4.1 dbContext – 删除具有不可空的外键关系的一对多数据对象
|
我正在使用MVC 3,EF 4.1和dbContext.我需要知道如何使用不可空的外键以一对多关系删除实体. 当我删除子实体并执行SaveChanges我得到错误: 操作失败:无法更改关系,因为一个或多个外键属性不可为空.当对关系进行更改时,将相关的外键属性设置为空值.如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,否则必须删除不相关的对象. 从其他帖子,我明白使用Remove(entity)标记该实体进行删除.在SaveChanges中,EF将外键设置为Null,并发生上述错误. 我发现在子实体上使用DeleteObject而不是Remove的一些帖子;但是,由于添加了dbContext和DbSet,因此DeleteObject方法似乎已被删除. 我发现建议修改EDMX外键关系为Nullable的帖子.修改EDMX是很好的,但是当数据库的更新模型完成时,这些更改将被禁用,并且必须重新应用.不是最佳的. 另一个帖子建议创建一个外键关系设置为Nullable的代理实体,但我不明白这种方法.它似乎与修改EDMX相同的问题,因为当保存对EDMX的更改时,上下文会自动更新. 我的简化模型是: 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; }
}
} public partial class UserContact
{
public long userContactId { get; set; }
public long userContactUserId { get; set; }
public long userContactTypeId { get; set; }
public string userContactData { get; set; }
public virtual ContactType ContactType { get; set; }
public virtual User User { get; set; }
}
userContactUserId和userContactTypeId是必需的外键. 在dbContext容器中,Users和UserContact都是DbSet. 我有一个ViewModel的用户和一个ViewModel的UserContact如下 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; }
}
将更改保存到用户配置文件时,我会循环使用UserContactViewModel实体列表,以确定哪些已添加,修改或删除. foreach (var c in model.Contacts)
{
UserContact uc = usr.UserContacts.Single(con => con.userContactId == c.UserContactId);
if (uc != null)
{
if (c.isDeleted == true) // Deleted UserContact
{
ctx.UserContacts.Remove(uc); // Remove doesn't work
}
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 { userContactUserId = model.UserId,userContactData = c.ContactData,userContactTypeId = c.ContactType });
}
}
我会感谢任何帮助. 解决方法我设法解决了以下问题:首先,我可以通过将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();
希望这能帮助未来的人. (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-4 – ASP.NET Web API的自定义MVC AuthorizeAt
- asp.net-mvc – 将DTO转换为ViewModel的位置?
- asp.net – jqgrid editurl:控制器动作参数
- asp.net – 有没有= window.onload在Javascript?
- asp.net-mvc-3 – Asp.net mvc 3-获取当前控制器实例(不只是
- asp.net-mvc – 通过Gitignore递归地包含Nuget DLL
- 下载期间的ASP.net内存使用情况
- asp.net – AppHarbor:不允许使用目录’/ App_GlobalResou
- asp.net – 如何获取控制器和操作名称在OnActionExecuting?
- asp.net – 运行Quartz.NET嵌入式或作为Windows服务的优点和
- asp.net – .resx vs数据库vs用于提供本地化/全球
- asp.net-mvc – ASP.NET MVC – CustomeAuthoriz
- asp.net – 我们可以在网页中使用多种形式吗?
- msbuild – 通过TFS 2015部署ASP.NET 5(vNext)
- asp.net-mvc-4 – 创建和编辑MVC4的相同视图
- asp.net-mvc – MVC 5防止通过iframe访问内容
- asp.net-mvc – 避免“类或CssClass值未定义”AS
- asp.net – 无法加载类型’System.ServiceModel.
- asp.net-mvc – DropDownList设置在asp.net MVC中
- iis – “立即启动应用程序池”和“启动模式Alwa
