首页 / C# / c# – EF急切加载导航属性问题
c# – EF急切加载导航属性问题
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – EF急切加载导航属性问题,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3219字,纯文字阅读大概需要5分钟。
内容图文
![c# – EF急切加载导航属性问题](/upload/InfoBanner/zyjiaocheng/781/47265f20c95940b4b186367b24ecc373.jpg)
我使用EF6与Generic Repository模式.最近我在尝试一次性删除复合实体时遇到了问题.这是一个简化的场景:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Parent")]
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
要删除具有相关子项的Parent实体,我正在执行以下操作:
public virtual T GetById(int id)
{
return this.DBSet.Find(id);
}
public virtual void Delete(T entity)
{
DbEntityEntry entry = this.Context.Entry(entity);
if (entry.State != EntityState.Deleted)
{
entry.State = EntityState.Deleted;
}
else
{
this.DBSet.Attach(entity);
this.DBSet.Remove(entity);
}
}
首先,我通过ID找到父对象,然后将其传递给delete方法,将其状态更改为已删除. context.SaveChanges()最终提交删除.
这很好. find方法只提取了Parent对象而Delete工作,因为我在Children上启用了删除级联.
但是我在Child类中添加了另一个属性的那一刻:
[ForeignKey("Gender")]
public int GenderId { get; set; }
public virtual Gender Gender { get; set; }
出于某种原因,EF开始在Parent.Find()方法中提取相关的Children.因此,我收到以下错误:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
即使在还原更改(删除Gender属性)后,问题仍然存在.我无法理解这种奇怪的行为!!
我想做的就是删除Parent对象和Children.
围绕它有一些解决方案,但没有一个真正符合我的目的:
>将LazyLoading转为false – this.Configuration.LazyLoadingEnabled = false;这有效,但在我的实际应用程序中,我需要此属性为true.
>首先迭代所有孩子并删除它们,然后删除父项.这似乎充其量只是一种解决方法,而且非常冗长.
>使用Remove()而不是仅仅将EntityState更改为Deleted.我需要跟踪审核更改,以便EntityState帮助那里.
有人可以解释为什么EF加载相关实体即使我不使用它们?
解决方法:
这个问题似乎与背景的生命周期有关.我正在使用工作单元并使用ninject将其注入我的服务层.
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
UnitOWork类实现IDisposable.
public bool DeleteView(int viewId)
{
// This is a workaround. It seems ninject is not disposing the context.
// Because of that all the info (navigation properties) of a newly created view is presisted in the context.
// Hence you get a referential key error when you try to delete a composite object.
using (var context = new ApplicationDbContext())
{
var repo = new GenericRepository<CustomView>(context);
var view = repo.GetById(viewId);
repo.Delete(view);
context.SaveChanges();
}
//var model = _unitOfWork.CustomViews.GetById(viewId);
//_unitOfWork.CustomViews.Delete(model);
//_unitOfWork.Save();
return true;
}
注释的代码抛出和错误,而未注释的代码(使用块)工作.此调用之前的控制器方法加载CustomView实体(其结构与Parent类似,具有子项列表).并且可以触发后续用户操作以删除该视图.
我认为这与未被处置的背景有关.也许这与Ninject或UnitOfWork有关,我还没有能够指出. GetById()可能会从上下文缓存或其他东西中拉出整个实体.
但上述解决方法对我有用.只是把它放在那里,以便它可以帮助某人.
内容总结
以上是互联网集市为您收集整理的c# – EF急切加载导航属性问题全部内容,希望文章能够帮你解决c# – EF急切加载导航属性问题所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。