所以我是 EF 新手(我正在使用 EF6),并且我在理解这个概念时遇到问题,我正在尝试使用子集合更新实体。
这是我的实体类:
public class TimeSheet
{
public int TimeSheetID { get; set; }
public virtual ICollection<TimeSheetDetail> Details { get; set; }
}
public class TimeSheetDetail
{
public int TimeSheetDetailID { get; set; }
public int TimeSheetID { get; set; }
public virtual TimeSheet TimeSheet { get; set; }
}
我的更新方法:
public void Update(TimeSheet obj)
{
var objFromDB = Get(obj.TimeSheetID);
var deletedDetails = objFromDB.Details.Except(obj.Details).ToList();
_dbContext.Entry(obj).State = EntityState.Modified;
//track if details exist
foreach (var details in obj.Details)
{
_dbContext.Entry(details).State = details.TimeSheetDetailID == 0 ? EntityState.Added : EntityState.Modified;
}
//track deleted item
foreach (var deleted in deletedDetails)
{
_dbContext.Entry(deleted).State = EntityState.Deleted;
}
}
public TimeSheet Get(object id)
{
//return _timeSheet.Find(id); //Without AsNoTracking I got error
int x = Convert.ToInt32(id);
return _timeSheet.AsNoTracking().SingleOrDefault(a => a.TimeSheetID == x);
}
上面的代码给我Attaching an entity of type 'ClassName' failed because another entity of the same type already has the same primary key value
。所以我的问题是:
如何使用 EF 更新子集合?意味着如果数据库中不存在我需要添加新的,否则更新,或者如果它在数据库中删除则从数据库中删除POST
.
如果我不使用AsNoTracking()
,它会抛出Saving or accepting changes failed because more than one entity of type 'ClassName' have the same primary key value
。我注意到该错误是由我造成的DbSet
将数据库中的数据添加到其Local
如果我不使用财产AsNoTracking()
这会导致 EF 框架抛出错误,因为它认为我有重复的数据。这实际上是如何运作的?
正如你所看到的,我正在尝试比较objFromDb
反对obj
检查用户是否删除了其中一项详细信息,以便我可以将其从数据库中删除。相反,我得到了一堆DynamicProxies
从采集结果来看。什么是DynamicProxies
它是如何运作的?
有没有关于 EF 的好文章或 101 教程?到目前为止,我只看到一个简单的答案,这对我的情况没有帮助,我环顾四周,找到了如何做事情的混合答案。老实说,此时我希望我只使用经典的 ADO.Net 而不是 EF。
为了更好地理解实体框架,请考虑DbContext
作为应用程序和数据库之间的代理。
这DbContext
将缓存所有内容并使用缓存值中的所有数据,除非您告诉它不要这样做。
For 1.:这取决于您的环境,如果您DbContext
不在选择和更新实体之间进行处理,您可以简单地调用SaveChanges
并且您的数据将被保存。如果你的DbContext
处理完毕后,您可以将实体从上下文中分离出来,更改数据,重新附加它们并设置EntityState
来修改。
我无法给你100%肯定的答案,因为我大约半年前就停止使用实体框架了。但我知道更新复杂的关系是一件痛苦的事。
For 2.: 命令AsNoTracking
告诉 EF 不要跟踪对此查询内的实体所做的更改。例如,您从数据库中选择 5 个时间表,更改第一个实体中的一些值并删除最后一个实体。这DbContext
知道第一个实体已更改,最后一个实体已删除,如果您调用SaveChanges
the DbContext
将自动更新第一个实体,删除最后一个实体,并保持其他实体不变。现在,您尝试自己更新实体并将第一个实体再次附加到 DbContext。
DbContext 现在将有两个具有相同键的实体,这会导致异常。
For 3.: The DynamicProxies
是实体框架用来跟踪这些实体的变化的对象。
For 4.:检查这个link http://www.entityframeworktutorial.net/,还有一本关于实体框架6的好书(书名:《编程实体框架》)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)