如何让ODATA序列化NotMapped属性

问题描述 投票:0回答:5

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

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

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

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

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

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

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

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

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

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

c# entity-framework asp.net-web-api odata
5个回答
10
投票

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

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

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


6
投票

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

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

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

对于 EF6,您还应该看看这个问题:EF Code First 阻止使用 Fluent API 进行属性映射


2
投票

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

请检查此答案,其中包含执行此操作的实现详细信息:将针对 DTO 的 OData 查询映射到另一个实体?

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


0
投票

如果您遇到此问题,上述建议在更高版本的 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
}

神奇的一块是二传手。


0
投票

这里是 goroths 答案的概括

foreach(var type in modelBuilder.StructuralTypes)
{
    foreach (var property in GetNotMappedProperties(type.ClrType))
        type.AddProperty(property);
}


private static IEnumerable<PropertyInfo> GetNotMappedProperties(Type type) =>
        type.GetProperties().Where(p => p.GetCustomAttribute<NotMappedAttribute>() != null);

还可以使用自定义属性来注释您仍想包含在 OData 中的那些 NotMapped 属性。

© www.soinside.com 2019 - 2024. All rights reserved.