Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 首先使用EF 4.3代码更新实体_.net_Database_Entity Framework - Fatal编程技术网

.net 首先使用EF 4.3代码更新实体

.net 首先使用EF 4.3代码更新实体,.net,database,entity-framework,.net,Database,Entity Framework,我有以下实体 public class Item { public int Id { get; set; } public string Name { get; set; } public Sections Sections { get; set; } } public class Section { public int ID { get; set; } public string Name { get; set; } } public class

我有以下实体

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Sections Sections { get; set; }
}

public class Section
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class Sections : List<Section>, ICollection<Section>
{ }
通过这样做,新的部分并没有被添加到数据库中。然后,在调用ctx2.SaveChanges之前,我修改了代码并添加了以下行

            ctx2.Entry(nsec).State = EntityState.Added;
它被成功保存

现在,我的问题是我有非常复杂的数据层次结构,我的意思是Section类也有很多子导航属性,这些属性也有很多子导航属性,等等

很难跟踪所有这些属性并手动设置它们的状态。在这种情况下,如何更新数据

还有一件事,我不会使用即时加载,我的意思是在检索Item对象时我不会使用Include。我将在需要时使用显式加载,并最终希望更新对象


有什么好的建议吗?

设置状态只影响传递给Entry调用的单个实体。使用新的上下文实例进行数据持久化后,必须始终告知要保存的任何实体的EF状态

在您的情况下,您需要执行以下任一操作:

ctx2.Items.Attach(fAp); // Now you informed context about existing entity
fAp.Sections.Add(nsec); // Now you told both context and your item that new section exists
或此首选解决方案以避免其他一些问题:

fAp.Sections.Add(nsec); // Your item is not tracked by the new context yet
ctx2.Items.Add(fAp);     // Now context things that both item and section are new
ctx2.Entry(fAp).State = EntityState.Unchanged; // Make sure that item is not inserted again
或者这个:

fAp.Sections.Add(nsec); // Your item is not tracked by the new context yet
ctx2.Items.Attach(fAp); // Now context things that both item and section are existing
ctx2.Entry(nsec).State = EntityState.Added; // Make sure that section is tracked as new 
很难跟踪所有这些属性并设置 手动更改其状态。在这种情况下,如何更新数据

您的代码正在进行这些更改,因此应该不会太困难。您甚至可以向每个实体添加一些附加属性,如IsDirty,并将其用作跟踪实体状态的辅助工具。

已更新实体

public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Sections Sections { get; set; }
    public OtherInfo Info { get; set; }
}
public class OtherInfo
{
    public Guid Id {get;set;}
    public string Description {get;set;}
}
检索项的对象后,用户可以修改任何内容。例如,如上所述,用户只是插入一个新的节,并通过传递对象项来调用commit方法

存储库类中的提交方法

public void Commit(Item fAp)
{
    using (var ct = new MyContext())
    {
        bool isExist = ct.Item.Any(a => a.Id == fAp.Id);
        if (!isExist)
        {
           ct.Items.Add(fAp);
        }
        else
        {
           ct.Items.Attach(fAp);
           ct.Entry(fAp).State = EntityState.Modified;
        }
        ct.SaveChanges();
    }
}
在这里的commit方法中,我不知道用户对对象做了什么。在我的测试中,我添加了节并调用了这个方法。由于未修改OtherInfo,因此其抛出错误表示OtherInfo表的主键重复

所以,为了让它工作,我必须改变所有实体的状态,比如

增加了一节;其他信息-无更改;项目-无变更

看起来很难跟踪所有实体,因为结构有点复杂


这种提交方法行吗?还是有更好的建议?

谢谢@Ladislav我无法控制客户端如何更新我的对象。我已经创建了存储库,客户在其中请求项目。然后再次调用commit方法。因为这里有一个空间限制,我在下面详细回应了它。。。
public void Commit(Item fAp)
{
    using (var ct = new MyContext())
    {
        bool isExist = ct.Item.Any(a => a.Id == fAp.Id);
        if (!isExist)
        {
           ct.Items.Add(fAp);
        }
        else
        {
           ct.Items.Attach(fAp);
           ct.Entry(fAp).State = EntityState.Modified;
        }
        ct.SaveChanges();
    }
}