OData只读属性

我有一个带OData V4的WebAPI 2.2应用程序。 我也在使用EF 6.1。

在我的一个实体中,我有一个计算属性:

public class Person { public string FirstName { get; set; } public string LastName { get; set; } // Calculated Property - No setter public string FullName { get { return FirstName + " " + LastName; } } 

为了向我的客户提供计算属性,我需要在OData模型中注册

  public static IEdmModel GetModel() { ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.Namespace = "NavigationServices"; builder.EntityType; builder.EntityType().Property(a => a.FullName); // Calculated Property .... return builder.GetEdmModel(); } 

因此,当我在客户端获取数据时,每个对象都具有Calculated属性。

但是,当我尝试创建(POST)新元素或更新(PUT)现有元素时,我的操作无法识别该元素并生成错误,表明它没有找到该属性的“set方法”。

我读了几篇关于OData中只读属性的post(显然不支持),但是我没有找到一种方法来使用带有计算属性的OData。

关于如何克服这种情况的一些建议?

现在有一种简单的方法可以做到这一点,即使用注释在客户端和服务器之间建立合同。

在V4标准的核心词汇表中 ,有一个这样的术语:

    

在Web API OData中,在WebConfig.cs中,您编写此类代码以将此类注释添加到您的属性中:

 ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); var model = builder.GetEdmModel() as EdmModel; model.SetVocabularyAnnotation( new EdmAnnotation(model.EntityContainer.FindEntitySet("People").EntityType().FindProperty("FullName"), new EdmTerm("Org.OData.Core.V1", "Computed", EdmPrimitiveTypeKind.Boolean), new EdmBooleanConstant(true))); 

然后在您的数据中,它看起来像这样:

    

通过上述步骤,服务通告服务计算Person实体上的FullName属性。 然后在POST和PATCH请求的控制器方法中,您可以拥有自己的逻辑,忽略客户端为FullName属性发送的任何值并计算您自己的值。

我不确定你使用的是哪个客户端。 如果您正在使用OData Client for .NET ,我们对获取注释值的支持将在我们的下一个版本中。 如果您不介意直接使用EdmLib ,则已添加注释值检索支持。

你说得对, OData目前不支持read-only properties

但是,它支持read-only entities

或者,您可以通过添加一个对您的property不起作用的setter来欺骗OData

 public string FullName { get { return FirstName + " " + LastName; } set { // do nothing } } 

这是您将entity设置为只读的方式:

 public class Northwind : DataService { // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config) { config.SetEntitySetAccessRule("Customers", EntitySetRights.AllRead); } } 

您可以使用数据库计算属性而不是类计算属性。

本文介绍EF和数据库计算属性。 与文章相比,我在示例代码中看到的一个区别是您的属性中没有任何setter。 如果将属性设置为使用具有私有集的自动访问器

 public string FullName { get; private set; } 

然后在数据库中将列创建为计算列。

 ALTER TABLE dbo.Users ADD FullName AS FirstName + ' ' + LastName 

作为额外的加号,您将能够使用odata和Linq查询此属性。