Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.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
C#EntityFramework:更新/添加/删除任意复杂的实体图_C#_Entity Framework - Fatal编程技术网

C#EntityFramework:更新/添加/删除任意复杂的实体图

C#EntityFramework:更新/添加/删除任意复杂的实体图,c#,entity-framework,C#,Entity Framework,我正在尝试在前端使用REACT.JS,在后端使用基于C#EntityFramework的RESTAPI开发应用程序 假设我有如下实体关系: Form ONE-TO-MANY Element Element ONE-TO_MANY Attribute 我试图做的是一个简单的控制器,它可以简单地添加/更新/删除这样的表单和所有相关的实体 我在REACT中创建了一个应用程序,其结构如下: <SyncComponent> <FormComponent>

我正在尝试在前端使用REACT.JS,在后端使用基于C#EntityFramework的RESTAPI开发应用程序

假设我有如下实体关系:

Form ONE-TO-MANY Element
Element ONE-TO_MANY Attribute
我试图做的是一个简单的控制器,它可以简单地添加/更新/删除这样的表单和所有相关的实体

我在REACT中创建了一个应用程序,其结构如下:

<SyncComponent>
    <FormComponent>
        <ElementsList>
            <ElementComponent>
                <AttributesList>
                    <AttributeComponent>
  • 新的
    元素
    添加到现有的
    表单

    {"id": 1, "name":"MyExistingForm", "elements":[{"name":"MyNewElement","attributes":[{"name":"MyNewAttribute","value":"MyValue"}]}]}
    
  • 更新了现有
    元素
    中的属性,并将新的
    元素
    添加到
    表单

    {  
        "id":123,
        "name":"MyExistingForm",
        "elements":[  
            {  
                "id":321
                "name":"MyExistingElement",
                "attributes":[  
                    {
                        "id":456 
                        "name":"MyExisitngAttribute",
                        "value":"MyUpdatedValue"
                    },
                    {
                        "name":"MyNewAttribute",
                        "value":"MyNewValue"
                    }
                ]
            },
            {  
                "name":"MyNewElement",
                "attributes":[  
                    {  
                        "name":"MyNewAttribute",
                        "value":"MyNewValue"
                    }
                ]
            }
        ]
    }
    
  • 。。。因此,基本上是一个具有任意分布的创建和更新任务的树(如果JSON中缺少elemnt,则会调用DELETE任务,但它存在于由数据库构造的数据库/对象表示中)。我知道只有在发生小的更改时才需要发送整个大对象,但我发现还是比在每个实体更改上发送单独的请求要好得多。首先,我认为我的方法更容易在客户端实现,其次,我将以一个请求而不是十几个请求结束,最后,应用程序将允许用户对表单进行多次更改,完成后,点击“保存”按钮更新状态。这样,我就不会陷入不一致的状态,例如,某些AJAX请求会失败,而有些则不会

    为了在服务器端同步这个JSON,我自动生成了MVCAPI控制器

    我遇到的问题是EntityFramework无法正确地将给定的JSON解析为任意深度的对象图。它适用于深度1,但不适用于深度1

    举例说明: 当invking
    PutForm()
    函数(查看下面的代码)时,
    form
    属性包含
    form
    的实例,
    form.elements
    包含传递的
    元素的集合,但是
    form.elements.toList[0]。属性始终为空,即使在JSON中传递了一些
    属性
    s

    namespace MyApp.Controllers
    {
        public class FormController : ApiController
        {
            private FormAsAServiceDbContext db = new FormAsAServiceDbContext();
    
            // ...
    
            // PUT: api/Form/5
            [ResponseType(typeof(void))]
            public async Task<IHttpActionResult> PutForm(int id, Form form)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                if (id != form.Id)
                {
                    return BadRequest();
                }
    
                db.Entry(form).State = System.Data.Entity.EntityState.Modified;
    
                try
                {
                    await db.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!FormExists(id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return StatusCode(HttpStatusCode.NoContent);
            }
    
            // ...
        }
    }
    
    名称空间MyApp.Controllers
    {
    公共类FormController:ApicController
    {
    private FormAsAServiceDbContext db=new FormAsAServiceDbContext();
    // ...
    //PUT:api/Form/5
    [响应类型(typeof(void))]
    公共异步任务PutForm(int-id,Form)
    {
    如果(!ModelState.IsValid)
    {
    返回请求(ModelState);
    }
    if(id!=form.id)
    {
    返回请求();
    }
    db.Entry(form).State=System.Data.Entity.EntityState.Modified;
    尝试
    {
    等待db.saveChangesSync();
    }
    catch(DbUpdateConcurrencyException)
    {
    如果(!FormExists(id))
    {
    返回NotFound();
    }
    其他的
    {
    投掷;
    }
    }
    返回状态码(HttpStatusCode.NoContent);
    }
    // ...
    }
    }
    

    我如何强制EntityFramework正确地从JSON构建完整的对象图,因为我可以执行原子更新/创建/删除这个任意复杂的实体图?

    @Brett Caswell你完全正确


    您就您的问题提供的最相关信息是 form.elements.toList[0]。属性始终为空,即使。。。 “已传递属性”


    长描述,简单问题。集合
    属性的名称
    与模型对象中的属性不完全对应,所以一旦我更改了它,映射就开始工作(到任何深度),所以现在我只需要迭代它们并将状态设置为“添加”或“修改”,这取决于ID是否为0。

    首先,图形是一个不寻常的术语,在描述概念上不同的事物时使用它:即对象、模型或类型。第二,实体是由ef上下文启动(实例)的模型;插入的情况除外<代码>数据库条目(表单)
    需要附加(添加状态)才能修改。您需要在该操作中满足任何外键约束。什么是
    FormAsAServiceDbContext
    ,它看起来像是一个完全泄漏的抽象。哦。。没关系,我看到你正试图修改现有表单。。不过,您应该查询表单实例的上下文,并将元素放入entities集合中。。无论如何,这里的问题纯粹是ajax发布和mvc框架序列化。您引用的JSON,您已经验证了这是web developer tools发布的内容吗?您在问题中提供的最相关信息是“form.elements.toList[0]。属性始终为空,即使…传递了属性”。。。它通常是确定“深度”或递归的序列化设置。尽管如此,我不确定修改
    表单
    类型实例的状态是否一定会传播或反映
    数据库集
    的状态更改(假定这是存储库和实体类型名称),即使属性已序列化..MVC中的默认“深度”级别为100,因此问题不大可能出现。。除非你在某个地方把它设为1。。更新您的问题,并包括实际的.NET类/模型/实体。。特别是
    表单
    属性
    。。另外,可以随意删除上下文外的信息,如REACT标记,只需提供1个JSON片段。。在这方面有点TMI。。。EF似乎也与您的问题有点脱节,但是您的方法和实现即使在解决了序列化问题之后也可以很好地提供相关的结果。
    namespace MyApp.Controllers
    {
        public class FormController : ApiController
        {
            private FormAsAServiceDbContext db = new FormAsAServiceDbContext();
    
            // ...
    
            // PUT: api/Form/5
            [ResponseType(typeof(void))]
            public async Task<IHttpActionResult> PutForm(int id, Form form)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                if (id != form.Id)
                {
                    return BadRequest();
                }
    
                db.Entry(form).State = System.Data.Entity.EntityState.Modified;
    
                try
                {
                    await db.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!FormExists(id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return StatusCode(HttpStatusCode.NoContent);
            }
    
            // ...
        }
    }