Entity framework OData包括;自定义属性“;通过分部类添加到实体框架模型

Entity framework OData包括;自定义属性“;通过分部类添加到实体框架模型,entity-framework,odata,Entity Framework,Odata,我制作了一个分部类文件,以便向实体框架生成的模型添加新属性 我使用的是WebAPI+OData,$metadata没有列出我的新/自定义属性,因此它返回的JSON不包括我的新/自定义属性 例如,假设我的实体是“Person” “人”有一个数据库属性;裸体;以$metadata形式返回的int,如下所示: 这很好,但我在一个单独的文件中添加了这样的属性 如何在OData响应中获得此属性 目前,如果我在$expand中请求MarriedStatus(就好像它是一个NavigationProper

我制作了一个分部类文件,以便向实体框架生成的模型添加新属性

我使用的是WebAPI+OData,$metadata没有列出我的新/自定义属性,因此它返回的JSON不包括我的新/自定义属性

例如,假设我的实体是“Person”

“人”有一个数据库属性;裸体;以$metadata形式返回的int,如下所示:

这很好,但我在一个单独的文件中添加了这样的属性

如何在OData响应中获得此属性

目前,如果我在
$expand
中请求
MarriedStatus
(就好像它是一个NavigationProperty…它不是[我想我无论如何都会尝试$expand,就好像它神奇地提供了自定义属性]),我会得到如下消息:

{
  "odata.error":{
    "code":"","message":{
      "lang":"en-US","value":"The query specified in the URI is not valid. Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'."
},"innererror":{
  "message":"Could not find a property named 'MarriedStatus' on type 'fakeDataModels.Person'.","type":"Microsoft.Data.OData.ODataException","stacktrace":"   at ..."
    }
  }
}

MarriedStatus
是一个计算/只读属性。OData的ASP.NET实现目前不支持此类属性。作为一种解决方法,添加一个setter,该setter抛出
NotImplementedException

    public string MarriedStatus {
        get { return this.NumSpouses > 0 ? "Married" : "Single"; }
        set { throw new NotImplementedException(); }
    }

或者,如果您使用的是OData V4,您可以注释
MarriedStatus
,以指定它是计算出来的。注意。但注释只是建议性的;它不会阻止客户端尝试设置计算属性(例如,在
POST
请求中)。

除了lencharest的答案之外。您应该使用实体框架fluent API的Ignore()函数,而不是[NotMapped]属性。因为OData查找此属性时会忽略序列化的属性。如果使用fluent API,则不会出现此问题

dbModelBuilder.Entity<TEntity>()
    .Ignore(i => i.ComputedProperty);
dbModelBuilder.Entity()
.Ignore(i=>i.ComputedProperty);

您的分部类是否与EF生成的模型位于同一命名空间中?是的。名称空间在两个文件中都是一致的,我们称之为“PersonDataModels”,并且两个文件都在同一个项目中。我知道
Controller.Json
Json序列化与OData序列化不同,但我要指出,除非我明确地说不(
ScriptIgnoreAttribute
),否则Json将序列化
MarriedStatus
属性。也许这需要一个等价的“ViewModel”,我应该添加到我的客户端(Javascript)代码中,这将为我提供方便的函数
getMarriedStatus()
。在我创建的玩具项目中,部分类可以按预期工作。可能问题在于您的OData配置。您使用的是
ODataConventionModelBuilder
,只是注册实体集吗?或者更复杂的东西?我给你看的是假的代码,而不是我的真实代码(为了隐藏我的业务目标/逻辑)。但我认为我只是在注册实体集;我有这样的等价物:
ODataConventionModelBuilder builder=new-ODataConventionModelBuilder();建造商实体集(“人”);config.Routes.MapODataRoute(“odata”,“odata”,builder.GetEdmModel())我把这个玩具写成了一本书。该配置是为在OWIN下运行而设计的,但是您应该仍然能够了解我所做的工作。注意,我调用的是
config.MapODataServiceRoute
,而不是
config.Routes.MapODataRoute
。您的项目是OData V3还是V4?但是,当尝试序列化属性时,仍然存在一个问题,因为如果存在setter并且该属性在数据库中不存在,LINQ to Entities将阻塞。请参阅,但我想包括更多列。。。我不想忽略列。我看不出Ignore/NotMapped是如何相关的请注意.Ignore()只是告诉实体框架忽略这个属性,就好像它不在数据库中一样。因此,对于插入、选择和更新,它将忽略此选项,同时仍然允许您在模型上使用它。这样,您可以添加任何您想要的内容。我还提供了@MylesRip的答案。
dbModelBuilder.Entity<TEntity>()
    .Ignore(i => i.ComputedProperty);