Asp.net web api 如何在Web Api OData中使用数据库生成的标识密钥

Asp.net web api 如何在Web Api OData中使用数据库生成的标识密钥,asp.net-web-api,odata,Asp.net Web Api,Odata,我已经按照以下教程创建了大量只读Web Api OData服务:。因此,我使用ODataConventionModelBuilder从一组实体(顺便说一下,来自Telerik ORM)创建模型。这一切似乎都很好,我可以很高兴地发出查询,查看元数据等服务 我现在试着把注意力转移到其他CRUD操作上——首先是创建,但遇到了问题!也就是说,Post方法正确激发(CreateEntity),但实体参数为null-通过对ModelState.IsValid进行检查,它表明问题是一个null ID(key)

我已经按照以下教程创建了大量只读Web Api OData服务:。因此,我使用ODataConventionModelBuilder从一组实体(顺便说一下,来自Telerik ORM)创建模型。这一切似乎都很好,我可以很高兴地发出查询,查看元数据等服务

我现在试着把注意力转移到其他CRUD操作上——首先是创建,但遇到了问题!也就是说,Post方法正确激发(CreateEntity),但实体参数为null-通过对ModelState.IsValid进行检查,它表明问题是一个null ID(key)值。这并不奇怪,因为数据库为ID列使用数据库生成的标识,因此在将实体保存到数据库上下文中时将创建ID

因此,我尝试了各种方法将ID列标记为数据库生成的,但没有找到任何结果。奇怪的是,我甚至找不到有人要求这个的帖子——当然我不可能是唯一一个

我注意到,在查看EF modelbuilder(例如,此处:)时,似乎有一种方法可以使用.hasDatabaseGenerateOption属性影响模型生成器,但在System.Web.Http.OData等效项中不存在类似的选项

因此,问题是:

  • 是否有方法更改模型生成器(或其他东西),以便控制器接受对象并反序列化实体(即使使用空键值)
  • 如果是,我该怎么做
  • 若否,对其他方案有何建议?
  • 我意识到我可能只是从客户机请求中用一个整数值(在本例中)填充对象,但这似乎是a)语义错误,b)由于可能使用的客户机工具包,不一定总是可能的

    感谢所有的帮助

    非常感谢,


    J.

    您需要为insert创建一个不包含ID参数的viewmodel。使用Automapper将传入插入模型的属性映射到数据实体


    您遇到的问题是,ID是数据模型中的一个必需属性,因为它是您的PK,但在insert期间不应指定ID。在我的情况下,我的数据库生成的密钥是Guid

    作为一种解决方法,在我的TypeScript客户端代码中,我提交(通过http POST)具有空Guid的对象,如下所示:注意:ErrorId是键列

        let elmahEntry: ELMAH_Error = {
            Application: 'PTUnconvCost',
            Host: this.serviceConfig.url,
            Message: message,
            User: that.userService.currentUserEmail,
            AllXml: `<info><![CDATA[\r\n\r\n${JSON.stringify(info || {})}\r\n\r\n]]></info>`,
            Sequence: 1,
            Source: source,
            StatusCode: 0,
            TimeUtc: new Date(Date.now()),
            Type: '',
            ErrorId: '00000000-0000-0000-0000-000000000000'
        };
    

    谢谢你的想法,埃里克-对我来说,这似乎仍然是一个解决办法,而不是一个解决方案。虽然我承认这会起作用,但它实际上会强制创建其他方法,而不是解决ModelBuilder自动创建的OData模型的问题。当然,除非我误解了你的答案……这根本不是一个解决办法。这是一种插入视图模型,是MVC世界中非常常见的做法。您的控制器接受插入并返回完整的实体或仅返回ID。它最终是非常RESTful的。
        // POST: odata/ELMAH_Error
        public IHttpActionResult Post(ELMAH_Error eLMAH_Error)
        {
            if (eLMAH_Error.ErrorId == Guid.Empty)
            {
                eLMAH_Error.ErrorId = Guid.NewGuid();
            }
    
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
    
            db.ELMAH_Error.Add(eLMAH_Error);
    
            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateException)
            {
                if (ELMAH_ErrorExists(eLMAH_Error.ErrorId))
                {
                    return Conflict();
                }
                else
                {
                    throw;
                }
            }
    
            return Created(eLMAH_Error);
        }