C# 如何让IEdmEntityTypeReference.Key()以正确的顺序返回键?

C# 如何让IEdmEntityTypeReference.Key()以正确的顺序返回键?,c#,odata,C#,Odata,我和OData一起工作,我不太熟悉。当OData将实体附加到类中的上下文时,它们使用ODataResourceMetadataBuilder设置.Identity属性 ODataResourceMetadataBuilder entityMetadataBuilder = this.GetEntityMetadataBuilderInternal(descriptor); descriptor.EditLink = entityMetadataBuilder.GetEditLink(); de

我和OData一起工作,我不太熟悉。当OData将实体附加到类中的上下文时,它们使用ODataResourceMetadataBuilder设置.Identity属性

ODataResourceMetadataBuilder entityMetadataBuilder = this.GetEntityMetadataBuilderInternal(descriptor);

descriptor.EditLink = entityMetadataBuilder.GetEditLink();
descriptor.Identity = entityMetadataBuilder.GetId();
这将经历一系列的OData类,从开始,最终到达在OData中创建CompositeKey的位置

这些键是在我的类中使用键注释定义的

public class MyClass
{
    [Key, Column(Order = 0)]
    public Guid CompositeKeyB { get; set; }

    [Key, Column(Order = 1)]
    public Guid CompositeKeyA { get; set; }
}
请注意,这些键按字母顺序向后排列

当上面的代码运行以设置.Identity字段时,它将按照字母顺序给我键,而不是按照我在数据注释中指定的顺序

这是一个问题,因为检索实体时,键的顺序正确,因此它具有不同的.Identity属性,并且被视为与附加实例不同的单独实例。这意味着它不会用新数据更新附加的实体,并且会在上下文中创建实体的第二个副本


有没有一种简单的方法来纠正这个问题,或者我一直在编写自己的代码,以便使用反射按正确的顺序获取密钥?我目前看不到在IEdmEntityTypeReference.Key返回的IEdmStructuralProperty属性中查找Order值的方法。

出现此问题的原因是,在ClientedModel.GetorCreatedTypeInternal方法中,它在将属性排序为键和非键属性之前按名称对属性进行排序

// Problem is the .OrderBy in this line of code
foreach (PropertyInfo property in ClientTypeUtil.GetPropertiesOnType(type, /*declaredOnly*/edmBaseType != null).OrderBy(p => p.Name))
{
    IEdmProperty edmProperty = this.CreateEdmProperty((EdmStructuredType)entityType, property);
    loadedProperties.Add(edmProperty);

    if (edmBaseType == null && keyProperties.Any(k => k.DeclaringType == type && k.Name == property.Name))
    {
        Debug.Assert(edmProperty.PropertyKind == EdmPropertyKind.Structural, "edmProperty.PropertyKind == EdmPropertyKind.Structural");
        Debug.Assert(edmProperty.Type.TypeKind() == EdmTypeKind.Primitive || edmProperty.Type.TypeKind() == EdmTypeKind.Enum, "edmProperty.Type.TypeKind() == EdmTypeKind.Primitive || edmProperty.Type.TypeKind() == EdmTypeKind.Enum");
        loadedKeyProperties.Add((IEdmStructuralProperty)edmProperty);
    }
}
我们使用的解决方案是在之后将原始排序应用于复合键属性,尽管潜在的解决方案也可以是从foreach循环中删除.OrderByp=>p.Name。不过,我不确定这是否会导致其他问题,因此似乎最安全的做法是在复合键之后重新应用键排序顺序

if (loadedKeyProperties.Count > 1)
{
    var orderedKeyPropertyNames = keyProperties.Select(k => k.Name).ToList();
    loadedKeyProperties = loadedKeyProperties.OrderBy(k => orderedKeyPropertyNames.IndexOf(k.Name)).ToList();
}

在我看来,这似乎是Microsoft.OData.Client库中的一个bug。也许你可以在这里报告这个问题?谢谢,我相信一个同事会报告这个错误。我将在这里发布我们的解决方案,以防其他人遇到同样的问题。
if (loadedKeyProperties.Count > 1)
{
    var orderedKeyPropertyNames = keyProperties.Select(k => k.Name).ToList();
    loadedKeyProperties = loadedKeyProperties.OrderBy(k => orderedKeyPropertyNames.IndexOf(k.Name)).ToList();
}