混淆关于EF跟踪(更新与子集实体) [英] Confuse about tracking in EF (updating entity with child collection)

查看:834
本文介绍了混淆关于EF跟踪(更新与子集实体)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我是新来的EF(我使用EF6),我有问题理解概念,我试图更新子集合实体。



这是我的实体类:

 公共类的TimeSheet 
{
公众诠释TimeSheetID {搞定;组; }
公共虚拟的ICollection< TimeSheetDetail>详细信息{搞定;组; }
}

公共类TimeSheetDetail
{
公众诠释TimeSheetDetailID {搞定;组; }
公众诠释TimeSheetID {搞定;组; }
公共虚拟的TimeSheet的TimeSheet {搞定;组; }
}



我的更新方法:

 公共无效更新(OBJ的TimeSheet)
{
VAR objFromDB = GET(obj.TimeSheetID);
VAR deletedDetails = objFromDB.Details.Except(obj.Details).ToList();

_dbContext.Entry(OBJ).STATE = EntityState.Modified;

//如果跟踪的详细信息(在obj.Details VAR细节)存在
的foreach
{
_dbContext.Entry(详细信息).STATE = details.TimeSheetDetailID == 0? EntityState.Added:EntityState.Modified;
}

//跟踪已删除项目
的foreach(VAR在deletedDetails删除)
{
_dbContext.Entry(删除).STATE = EntityState.Deleted ;
}
}

公众的TimeSheet找(对象ID)
{
//返回_timeSheet.Find(ID); //没有AsNoTracking我得到了错误
INT X = Convert.ToInt32(ID);
返回_timeSheet.AsNoTracking()的SingleOrDefault(A => a.TimeSheetID == X);
}



以上代码给我附加类型的实体类名'失败,因为同类型的另一实体已经有相同的主键值。所以我的quesstion是:




  1. 如何更新子集合与EF?意味着我需要增加新的,如果它不存在的DB,否则更新,或从数据库中删除,如果它是在 POST


  2. 如果我不使用 AsNoTracking(),它会抛出保存或接受改变失败的原因多型类名中的一个实体,具有相同的主键值。我注意到,错误是由原因我 DbSet 从数据库中的数据添加到它的本地财产,如果我不使用 AsNoTracking()造成,因为它认为我有一个重复数据的EF框架抛出的错误。这是如何工作实际?


  3. 正如你可以看到我试图比较 objFromDb OBJ 来检查,如果用户删除的一个细节,所以我可以从数据库中删除。相反,我从收集结果 DynamicProxies 的一群。什么是 DynamicProxies ,它是如何工作的?


  4. 有没有什么好的文章或101教程EF ?到目前为止,我只看到一个简单的不利于我的情况和我环顾四周,发现一个混合的答案如何做的东西。说实话,在这一点上我希望我只想去与经典ADO.Net,而不是EF



解决方案

为了更好地了解实体框架,认为的DbContext 为您的应用程序和数据库之间的代理。
中的的DbContext 将缓存的一切,将使用的每一个数据从缓存的值,除非你告诉它不这样做。



对于1 :这取决于您的环境,如果你的的DbContext 未设置选择和更新的entites即可之间只是简单地调用的SaveChanges 和您的数据将被保存。如果你的的DbContext 配置可以分离从上下文中的entites,更改数据,重新连接它们并设置 EntityState 要修改。



我不能给你一个100%肯定的回答,因为我大约半年前停止使用实体框架。但我知道这是更新的复杂关系中的疼痛



对于2 :该命令 AsNoTracking 告诉EF不跟踪此查询中的实体所做的更改。例如从数据库中选择你5时间表,在第一实体改变一些值,并删除最后一个。在的DbContext 知道的第一个实体被改变,最后一个被删除,如果调用的SaveChanges 的DbContext 将自动更新的第一个实体,删除最后一个离开其他的人不变。现在你尝试自行更新实体,再附加的第一个实体到的DbContext。



的DbContext现在有两个entites的使用相同的密钥,这会导致你的。例外



对于3 :在 DynamicProxies 是对象的实体框架,用于跟踪这些实体的变化



对于4 :选中此的链接,也有关于实体框架6(标题一本好书:编程实体框架)


So I'm new to EF (I'm using EF6) and I have problem understanding the concept, I'm trying to update entity with child collection.

Here's my entity class :

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; }
}

My update method :

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);
}

Above code give me Attaching an entity of type 'ClassName' failed because another entity of the same type already has the same primary key value. So my quesstion is :

  1. How do you update child collection with EF? Means that I need to Add new if it doesn't exist in DB, update otherwise, or delete from DB if it is removed in the POST.

  2. If I don't use AsNoTracking(), it will throw Saving or accepting changes failed because more than one entity of type 'ClassName' have the same primary key value. I notice that the error was cause by my DbSet add the data from DB to its Local property if I don't use AsNoTracking() which cause the EF framework to throw the error because it thinks I have a duplicate data. How does this work actually?

  3. As you can see I'm trying to compare objFromDb against obj to check if user remove one of the details so I can remove it from the database. Instead I got bunch of DynamicProxies from the collection result. What is DynamicProxies and how does it work?

  4. Is there any good article or 101 tutorial on EF? So far I've only see a simple one which doesn't help my case and I've looking around and find a mixed answer how to do stuff. To be honest, at this point I wish I would just go with classic ADO.Net instead of EF.

解决方案

For a better understanding of the entity framework, think of the DbContext as proxy between your application and the database. The DbContext will cache everything and will use every bit of data from the cached values unless you tell it not to do so.

For 1.: This depends on your environment if your DbContext is not disposed between selecting and updating the entites you can simply just call SaveChanges and your data will be saved. If your DbContext is disposed you can detach the entites from the context, change the data, reattach them and set the EntityState to modified.

I can't give you a 100% sure answer, because I stopped using the entity framework about half a year ago. But I know it is a pain to update complex relations.

For 2.: The command AsNoTracking tells the EF not to track the changes made to the entities inside this query. For example your select 5 TimeSheets from your Database, change some values in the first entity and delete the last one. The DbContext knows that the first entity is changed and the last one is deleted, if you call SaveChanges the DbContext will automatically update the first entity , delete the last one and leave the other ones untouched. Now you try to update an entity by yourself and attach the first entity again to the DbContext.

The DbContext will now have two entites with the same key and this leads to your exception.

For 3.: The DynamicProxies is the object that the entity framework uses to track the changes of these entities.

For 4.: Check this link, also there is a good book about entity framework 6 (Title: "Programming Entity Framework")

这篇关于混淆关于EF跟踪(更新与子集实体)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆