Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Enums as Keys in OData Client #3013

Merged
merged 8 commits into from
Jul 22, 2024
4 changes: 3 additions & 1 deletion src/Microsoft.OData.Client/Metadata/ODataTypeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,9 @@ private PropertyInfo[] GetKeyProperties()
throw c.Error.InvalidOperation(c.Strings.ClientType_KeysOnDifferentDeclaredType(typeName));
}

if (!PrimitiveType.IsKnownType(key.PropertyType) && !(key.PropertyType.GetGenericTypeDefinition() == typeof(System.Nullable<>) && key.PropertyType.GetGenericArguments().First().IsEnum()))
// Check if the key property's type is a known primitive, an enum, or a nullable generic.
// If it doesn't meet any of these conditions, throw an InvalidOperationException.
if (!PrimitiveType.IsKnownType(key.PropertyType) && !key.PropertyType.IsEnum() && !(key.PropertyType.IsGenericType() && key.PropertyType.GetGenericTypeDefinition() == typeof(System.Nullable<>)))
WanjohiSammy marked this conversation as resolved.
Show resolved Hide resolved
{
throw c.Error.InvalidOperation(c.Strings.ClientType_KeysMustBeSimpleTypes(key.Name, typeName, key.PropertyType.FullName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using Microsoft.OData.Client.Metadata;
using System;
using System.Linq;
using Xunit;

namespace Microsoft.OData.Client.Tests.Metadata
Expand Down Expand Up @@ -50,6 +51,81 @@ public void IFTypeProperty_HasKeyAttributeAndOneProperty_TypeIsEntityAndDoesNotT
Assert.True(actualResult);
}

[Fact]
public void IFType_HasMultipleKeyAttributesWhereOneIsEnum_TypeIsEntityAndDoesNotThrowException()
{
//Arrange
Type employee = typeof(Employee);

//Act
bool actualResult = ClientTypeUtil.TypeOrElementTypeIsEntity(employee);

//Assert
Assert.True(actualResult);
}

[Fact]
public void IFTypeProperty_HasMultipleKeyAttributes_GetKeyPropertiesOnType_DoesNotThrowException()
{
//Arrange
Type employee = typeof(Employee);

int expectedNumberOfKeyProperties = 4; // 2 Primitive Known Types, 1 Enum Type, 1 Nullable Generic Type

//Act
var keyProperties = ClientTypeUtil.GetKeyPropertiesOnType(employee);

//Assert
Assert.Equal(expectedNumberOfKeyProperties, keyProperties.Length);
WanjohiSammy marked this conversation as resolved.
Show resolved Hide resolved
}

[Fact]
public void IFTypeProperty_HasEnumTypeKeyAttribute_GetKeyPropertiesOnType_DoesNotThrowException()
{
// Arrange
Type employee = typeof(Employee);

//Act
var keyProperties = ClientTypeUtil.GetKeyPropertiesOnType(employee);
var key = keyProperties.Single(k => k.Name == "EmpType");

//Assert
Assert.True(key.PropertyType.IsEnum());
Assert.True(key.PropertyType == typeof(EmployeeType));
}

[Fact]
public void IFTypeProperty_HasKnownPrimitiveTypesKeyAttributes_GetKeyPropertiesOnType_DoesNotThrowException()
{
// Arrange
Type employee = typeof(Employee);

//Act
var keyProperties = ClientTypeUtil.GetKeyPropertiesOnType(employee);

var empNumKey = keyProperties.Single(k => k.Name == "EmpNumber");
var deptNumKey = keyProperties.Single(k => k.Name == "DeptNumber");

//Assert
Assert.True(PrimitiveType.IsKnownType(empNumKey.PropertyType) && empNumKey.PropertyType == typeof(int));
Assert.True(PrimitiveType.IsKnownType(deptNumKey.PropertyType) && deptNumKey.PropertyType == typeof(string));
}

[Fact]
public void IFTypeProperty_HasNullableGenericTypeKeyAttribute_GetKeyPropertiesOnType_DoesNotThrowException()
{
// Arrange
Type employee = typeof(Employee);

//Act
var keyProperties = ClientTypeUtil.GetKeyPropertiesOnType(employee);
var key = keyProperties.Single(k => k.Name == "NullableId");

//Assert
Assert.True(key.PropertyType.IsGenericType);
Assert.True(key.PropertyType == typeof(System.Nullable<int>));
}

public class Person
{
[System.ComponentModel.DataAnnotations.Key]
Expand All @@ -69,5 +145,41 @@ public class Car
public int NonStandardId { get; set; }
}

public class Employee
{
[System.ComponentModel.DataAnnotations.Key]
public int EmpNumber { get; set; }

[System.ComponentModel.DataAnnotations.Key]
public string DeptNumber { get; set; }

[System.ComponentModel.DataAnnotations.Key]
public EmployeeType EmpType { get; set; }

[System.ComponentModel.DataAnnotations.Key]
public int? NullableId { get; set; }

public string Name { get; set; }

public decimal Salary { get; set; }

[System.ComponentModel.DataAnnotations.Schema.ForeignKey("DeptNumber")]
public Department Department { get; set; }
}

public enum EmployeeType
{
None = 1,
FullTime = 2,
PartTime = 3
}

public class Department
{
[System.ComponentModel.DataAnnotations.Key]
public string DeptId { get; set; }
public string Name { get; set; }
}

}
}