3

У меня есть следующий код:Web API 2 OData EDM Anomaly

public class AwardTitle 
{ 
    public int AwardTitleId 
    { 
     get; 
     set; 
    } 

    public int? EpisodeId 
    { 
     get; 
     set; 
    } 

    public virtual AwardEpisode Episode 
    { 
     get; 
     set; 
    } 
} 

public class AwardEpisode 
{ 
    public int EpisodeId 
    { 
     get; 
     set; 
    } 
} 

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     config.Routes.MapODataRoute("ODataRoute", "api", GetImplicitEDM()); 
    } 
} 

private static Microsoft.Data.Edm.IEdmModel GetImplicitEDM() 
{ 
    var builder = new ODataConventionModelBuilder(); 
    builder.EntitySet<AwardTitle>("AwardTitles"); 

    return builder.GetEdmModel(); 
} 

Обратите внимание, как я только отображенный в AwardTitle класс ... не AwardEpisode класс.

Теперь, когда я перехожу к контроллеру, я бы ожидал получить сообщение об ошибке, не отображающей AwardEpisode. Однако ошибок нет. Фактически, в дополнение к AwardTitle, который извлекается ... AwardEpisode также извлекается ... без каких-либо явных призывов сделать это.

Как это возможно ??? Должно ли это быть возможным?

Я использую ASP.Net Web API 2 на Windows 7.

+0

небось генератор EDM использует отражение для создания всех зависимых классов. Возможно, есть параметр, чтобы сообщить генератору шаблонов игнорировать класс. –

+0

Это по дизайну таким образом. – vittore

+0

vitore, я не думаю, что это по дизайну. Каждый раз, когда я реализую контроллер, зависимые классы не включаются, если я специально не прошу их использовать $ expand – Chris

ответ

1

ODataConventionModelBuilder по умолчанию карты типа А T «s примитивное, сложное и свойства навигации для вызова .EntitySet<TEntityType>(string name) апи. code является:

private void MapEntityType(EntityTypeConfiguration entity) 
{ 
    IEnumerable<PropertyInfo> properties = ConventionsHelpers.GetProperties(entity, includeReadOnly: _isQueryCompositionMode); 
    foreach (PropertyInfo property in properties) 
    { 
     bool isCollection; 
     StructuralTypeConfiguration mappedType; 

     PropertyKind propertyKind = GetPropertyType(property, out isCollection, out mappedType); 

     if (propertyKind == PropertyKind.Primitive || propertyKind == PropertyKind.Complex) 
     { 
      MapStructuralProperty(entity, property, propertyKind, isCollection); 
     } 
     else 
     { 
      // don't add this property if the user has already added it. 
      if (!entity.NavigationProperties.Where(p => p.Name == property.Name).Any()) 
      { 
       NavigationPropertyConfiguration addedNavigationProperty; 
       if (!isCollection) 
       { 
        addedNavigationProperty = entity.AddNavigationProperty(property, EdmMultiplicity.ZeroOrOne); 
       } 
       else 
       { 
        addedNavigationProperty = entity.AddNavigationProperty(property, EdmMultiplicity.Many); 
       } 

       addedNavigationProperty.AddedExplicitly = false; 
      } 
     } 
    } 

example испытательного корпуса:

public void ModelBuilder_Products() 
{ 
    var modelBuilder = new ODataConventionModelBuilder(); 
    modelBuilder.EntitySet<Product>("Products"); 

    var model = modelBuilder.GetEdmModel(); 

    var product = model.AssertHasEntitySet(entitySetName: "Products", mappedEntityClrType: typeof(Product)); 
    product.AssertHasPrimitiveProperty(model, "ReleaseDate", EdmPrimitiveTypeKind.DateTime, isNullable: true); 
    product.AssertHasComplexProperty(model, "Version", typeof(ProductVersion), isNullable: true); 
    product.AssertHasNavigationProperty(model, "Category", typeof(Category), isNullable: true, multiplicity: EdmMultiplicity.ZeroOrOne); 

Чтобы изменить поведение по умолчанию, мы можем игнорировать свойство:

var builder = new ODataConventionModelBuilder(); 
builder.Entity<AwardTitle>().Ignore(a => a.Episode); 
builder.EntitySet<AwardTitle>("AwardTitles"); 

return builder.GetEdmModel(); 
Смежные вопросы