相关疑难解决方法(0)

Web API Queryable - 如何应用AutoMapper?

我有一个像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)

.net asp.net asp.net-mvc asp.net-web-api

25
推荐指数
3
解决办法
1万
查看次数

定义Navigation属性时列出vs IEnumerable vs IQueryable

我想创建一个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)

linq entity-framework asp.net-mvc-3

14
推荐指数
2
解决办法
5113
查看次数

将DTO与OData和Web API结合使用

使用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 …

asp.net entity-framework automapper odata asp.net-web-api

10
推荐指数
1
解决办法
3041
查看次数

将ODATA $ expand查询选项与WebAPI和ViewModel一起使用

这个问题非常相似,但没有给我我所需要的。

我正在使用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

5
推荐指数
1
解决办法
2059
查看次数