使用DTO进行OData v3动态导航配置

时间:2017-05-24 13:40:31

标签: c# entity-framework asp.net-web-api2 odata odata-v3

我目前正在尝试配置我的OData服务以使用DTO作为返回类型,因为它将具有将从一个请求更改为另一个请求的属性。实体和DTO看起来有点像:

public class EntityA
{
    public int Id { get; set; }
    ...

    public virtual ICollection<EntityB> Bs { get; set; }
}

public class EntityB : IEntityB
{
    public int Id { get; set; }
    ... 

    public virtual EntityA A { get; set; }
}

public interface IEntityB
{
    // Various properties
}

public class MyDTO
{
    public IEntityB { get; set; }

    public IReadOnlyList<MySubDTO> SubDTOs { get; set; }
}

public class MySubDTO
{
    public string DynamicProp1 { get; set; }

    public string DynamicProp2 { get; set; }
}

我们的OData配置如下所示:

modelBuilder.EntitySet<EntityA>("EntityAs");
modelBuilder.EntitySet<EntityB>("EntityBs");
modelBuilder.EntitySet<MyDTO>("MyDTOs");

var myDTOs = (EdmEntitySet)model.EntityContainers().Single().FindEntitySet("MyDTOs");
var myDTOType = (EdmEntityType)model.FindDeclaredType("MyApplication.DTO.MyDTO");

var entityAs = (EdmEntitySet)model.EntityContainers().Single().FindEntitySet("EntityAs");
var entityAType = (EdmEntityType)model.FindDeclaredType("MyApplication.DAL.Entities.EntityA");

var myDTOEntityANav = participantsType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
{
    ContainsTarget = false,
    Name = "ActionableSchedules",
    Target = actionableSchedulesType,
    TargetMultiplicity = EdmMultiplicity.Many,
});

var entityAMyDTONav = actionableSchedulesType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
{
    ContainsTarget = false,
    Name = "Participant",
    Target = participantsType,
    TargetMultiplicity = EdmMultiplicity.One,
});

myDTOs.AddNavigationTarget(entityAMyDTONav, entityAs);
entityAs.AddNavigationTarget(myDTOEntityANav, myDTOs);

当在服务中接收到请求时,控制器方法中的查询查看特定EntityA的EntityB集合,并且基于EntityB上的某些属性的值,我们发回带有EntityBs的IReadOnlyList,并且我们添加了MySubDTO到MyDTO,它包含两个字符串属性,这些属性因请求而异。

一切正常,直到我们尝试发送回复。我得到的错误是:

  

未找到导航属性的NavigationLink工厂   来自实体类型的'EntityA'   实体集上的“MyApplication.DTO.MyDTO”   'MyDTOs'。尝试在上面调用HasNavigationPropertyLink   EntitySetConfiguration。参数名称:navigationProperty

我尝试在EntitySetConfiguration上添加HasNavigationPropertyLink,最后得到了一段代码如下:

entitySetConfiguration.HasNavigationPropertyLink(entitySetConfiguration.EntityType.NavigationProperties.First(np => np.Name == "EntityA"),
        (context, navigation) =>
    {
        return new Uri(context.Url.ODataLink(new EntitySetPathSegment("EntityA"),
            new KeyValuePathSegment(context.EntityInstance.EntityA.ID.ToString())));
    }, false);

为此,我必须将MyDTO更改为以下内容:

public class MyDTO
{
    public IEntityB { get; set; }

    public virtual EntityA EntityA { get; set; }

    public IReadOnlyList<MySubDTO> SubDTOs { get; set; }
}

然后将OData配置更新为以下内容:

var entitySetConfiguration = modelBuilder.EntitySet<MyDTO>("MyDTOs");
entitySetConfiguration.EntityType.HasOptional(p => p.EntityA);
  

“MyApplication.DTO.MyDTO”类型名为“EntityA”的属性具有   善待'无',但预计会有点'导航'。

我应该如何配置我的OData服务才能使其正常工作?

0 个答案:

没有答案