我有一个像OData可查询属性一样的简单WebApi方法.
[Queryable]
public virtual IQueryable<PersonDto> Get()
{
return uow.Person().GetAll()); // Currently returns Person instead of PersonD
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是在WebAPI将结果转换为JSON之前,使用AutoMapper将查询结果从Person类型转换为PersonDto类型.
有人知道我怎么做吗?我知道,我可以在GetAll()调用之后应用Mapper.Map,然后转换回IQueryable,但这会导致在应用OData过滤器之前返回并映射整个表(不好!).
看来这个问题ASP.NET Web API返回可查询的DTO?包含相同的问题(请参阅第二个响应以获得更好的答案),其中建议使用自定义MediaTypeFormatter在链的末尾使用AutoMapper,但是根据我看到的示例,我不知道如何做到这一点.
任何帮助将不胜感激!
- 更多信息
我已经查看了IQueryable的源代码,但遗憾的是我看不到为此目的使用代码的任何方法.我已经设法编写了一个看起来有效的附加过滤器,但它并不一定不优雅.
public class PersonToPersonDtoConvertAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
HttpResponseMessage response = actionExecutedContext.Response;
if (response != null)
{
ObjectContent responseContent = response.Content as ObjectContent;
var query = (responseContent.Value as IQueryable<Student>).ToList();
response.Content = new ObjectContent<IEnumerable<StudentResource>>(query.ToList().Select(Mapper.Map<Person, PersonDto>), responseContent.Formatter);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我装饰了这样的动作
[Queryable]
[PersonToPersonDtoConvert]
public IQueryable<Person> Get()
{
return uow.GetRepo<IRepository<Person>>().GetAll();
}
Run Code Online (Sandbox Code Playgroud) 我想创建一个Movie_Type在我的ASP.NET MVC Web应用程序中命名的新模型对象.如果我将此类的导航属性定义为或者如下List,那将会有什么不同?ICollectionIQueryable
public partial class Movie_Type
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Movie> Movies { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
要么
public partial class Movie_Type
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IQueryable<Movie> Movies { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
要么
public …Run Code Online (Sandbox Code Playgroud) 使用Web API和OData,我有一个服务,它公开数据传输对象而不是实体框架实体.
我使用AutoMapper将EF实体转换为其DTO计数器部件ProjectTo():
public class SalesOrdersController : ODataController
{
private DbContext _DbContext;
public SalesOrdersController(DbContext context)
{
_DbContext = context;
}
[EnableQuery]
public IQueryable<SalesOrderDto> Get(ODataQueryOptions<SalesOrderDto> queryOptions)
{
return _DbContext.SalesOrders.ProjectTo<SalesOrderDto>(AutoMapperConfig.Config);
}
[EnableQuery]
public IQueryable<SalesOrderDto> Get([FromODataUri] string key, ODataQueryOptions<SalesOrderDto> queryOptions)
{
return _DbContext.SalesOrders.Where(so => so.SalesOrderNumber == key)
.ProjectTo<SalesOrderDto>(AutoMapperConfig.Config);
}
}
Run Code Online (Sandbox Code Playgroud)
AutoMapper(V4.2.1)配置如下,请注意,ExplicitExpansion()当未请求时,会阻止序列化自动扩展导航属性:
cfg.CreateMap<SalesOrderHeader, SalesOrderDto>()
.ForMember(dest => dest.SalesOrderLines, opt => opt.ExplicitExpansion());
cfg.CreateMap<SalesOrderLine, SalesOrderLineDto>()
.ForMember(dest => dest.MasterStockRecord, opt => opt.ExplicitExpansion())
.ForMember(dest => dest.SalesOrderHeader, opt => opt.ExplicitExpansion());
Run Code Online (Sandbox Code Playgroud)
ExplicitExpansion() 然后创建一个新问题,其中以下请求引发错误:
/ odatademo/SalesOrders表( '123456')?$扩大= SalesOrderLines …
这个问题非常相似,但没有给我我所需要的。
我正在使用Entity Framework6。我的数据库有两个表,Customers和CustomerTypes。我为每个创建了一个ViewModel。客户可以具有以下类型:
public class Customer
{
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public CustomerTypeViewModel CustomerType { get; set; }
}
public class CustomerTypeViewModel
{
public int CustomerTypeID { get; set; }
public string CustomerTypeDescription { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个Customer控制器,它公开了具有IQueryable返回类型的odata操作方法:
[HttpPost, Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<CustomerViewModel> GetCustomersMatchingCriteria([FromBody]ODataActionParameters parameters)
{
var criteria = (CustomerMassUpdateCriteriaViewModel)parameters["Criteria"];
return Common.Customers.GetCustomerMassUpdateCriteriaResults(criteria,
ConfigurationManager.AppSettings["CLIENT_ID"]).Select(
c => new CustomerViewModel()
{
CustomerID = c.CustomerID,
CustomerName = c.CustomerName,
CustomerType = new …Run Code Online (Sandbox Code Playgroud) c# entity-framework odata asp.net-web-api asp.net-mvc-viewmodel