【问题标题】:How to get ODATA to serialize NotMapped property如何让 ODATA 序列化 NotMapped 属性
【发布时间】:2017-05-20 10:32:52
【问题描述】:

我有一个 WebAPI 后端,它使用 ODATA v3 向各种客户端提供库存信息等(由于我们使用的组件的限制,我不能使用 v4)。库存数据库非常大(超过 10 万条记录),ODATA 非常适合服务器端过滤、分页等,并保持数据传输精简。

库存记录具有一些未映射的属性,而是在进行查询时动态计算和填充的。例如:

[NotMapped]
public decimal RebateAmount { get; set; }

问题在于 ODATA 会忽略任何 NotMapped 属性,因此它们永远不会被发送回客户端。

我知道以前有人问过这个问题,但那是不久前的事了,所以 我希望现在已经添加了对此的支持,或者有人有一个简单的解决方法(没有让 EF在数据库中创建这些字段)。

我已经尝试过这种丑陋的解决方法,但它不起作用(ODATA 仍然不包含 RebateAmount):

private decimal _rebateAmount;
public decimal RebateAmount { get {return _rebateAmount; } }

public void SetRebateAmount(decimal amount)
{
   _rebateAmount = amount;
}

是否有一种(最好是简单的)方法可以在 ODATA 结果集中包含非 DB 属性?

2017 年 1 月 7 日编辑 为了在我的场景中有用,ODATA 还需要在其元数据中包含计算字段,否则自动生成的(客户端)代理类将不包含它们。

【问题讨论】:

    标签: c# entity-framework asp.net-web-api odata


    【解决方案1】:

    如果您遇到此问题,上述建议不适用于更高版本的 EF。我能够通过以下方式使用它:

    // Add this to the DB Context:
    // *****************************************
    modelBuilder.Entity<ModelObject>().Ignore(a => a.PropertyName);
    
    // Add this to the Model Object
    // *****************************************
    public string PropertyName { 
        get { return _expression1.Evaluate(this); } 
        set { }     // # This is the magic piece that makes it work
    }
    

    神奇的棋子是二传手。

    【讨论】:

      【解决方案2】:

      最简单的方法(至少对于 EF Core):使用 fluent-api!

      您可以像这样定义它,而不是 NotMapped-Attribute:

      modelBuilder.Entity<Product>().Ignore(p => p.RebateAmount);
      

      对于 EF6,您还应该看看这个问题:EF Code First prevent property mapping with Fluent API

      【讨论】:

      • 不适用于在 DataContract(C# 类)级别计算且与 DB 字段无关的字段
      【解决方案3】:

      我知道这是一篇旧帖子,但在 WebApiConfig 文件中只需添加以下内容,它将公开“NotMapped”属性。

      builder.StructuralTypes.First(t => t.ClrType == typeof(YourModel)).AddProperty(typeof(YourModel).GetProperty("RebateAmount"));
      

      其中“builder”是您的 IEdmModel。最有可能在您的“GetEdmModel”方法中。

      【讨论】:

      • 此解决方案在 Odata 版本 7.5x 中不起作用。它不生成元数据。有什么想法吗?
      • @Rahul 我刚刚检查了 7.5.4,它仍在工作。转到 odata/$metadata 时收到什么错误?如果您注释掉“AddProperty”的特定行,元数据是否仍会生成?
      • @goroth 我没有收到任何错误消息,但是当我浏览 odata/$metadata 时,它显示一个空白网页。如果我评论代码,那么我可以访问元数据页面。
      • @Rahul 您是在 IIS 还是 IIS Express 中托管?听起来你有一个更高级别的异常,你没有捕捉或隐藏。可能想在你的 global.asax Application_Start() 中添加一个 IExceptionHandler,也可能想在你的 WebApiConfig 中的 AddProperty 上放置一个断点,然后运行应用程序,它不会遇到断点,但是一旦它运行只需编辑你的web.config 通过添加一个空格并点击保存,这将强制 IIS 回收,然后您将点击断点来调试 WebApiConfig。
      【解决方案4】:

      一种方法是使用具有附加计算属性的 DTO 对象创建 OData EDMModel。

      请检查此答案,其中包含执行详细信息:Mapping OData query against a DTO to another entity?

      DTO 可以通过数据库服务器上的视图进行映射 或者可以在控制器中使用OdataQueryOptions 计算。

      【讨论】:

      • 我开始实施您的建议,但结果却增加了相当多的复杂性(这超出了我的承受能力);如果没有不那么侵入性的方法来实现这一点,我只会硬着头皮把属性放在数据库中。不过谢谢你的建议!
      • 我忘了提到我使用 ODATA 3(我已经更新了问题),所以这至少解释了我在尝试实施您的建议时遇到的一个问题。无论哪种方式,我都赞成您花时间提出可能的解决方案。
      • 我以前必须实现这样的案例,不幸的是我找不到任何更简单的解决方案,并使用 OdataQueryOptions 创建了一个自定义 IQueryable 来处理自定义 EdmModel。我会关注这个问题以获取有关更好解决方案的更新。
      • 我很好奇:您使用的是 ODATA 3 还是 ODATA 4?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 1970-01-01
      相关资源
      最近更新 更多