我们有一个带有IQueryable<T>
资源的API,因为我们使用OData。我的老板要求公开的资源也有数据库中没有的其他信息。
OData允许只选择他们需要的信息,它通过将$ select = Quantity查询参数映射到LINQ来执行此操作:执行.Select(s =&gt; s.Quantity)。这当然不起作用,因为LINQ to Entities会抱怨数据库中不存在该列。
public class Item
{
public int Id { get; set; }
public int Quantity
{
get { return SubItems.Count; }
set {}
}
public virtual ICollection<SubItem> SubItems { get; set; }
}
我需要解决这个限制。我已经研究过AutoMapper,但是当.ProjectTo()
与IValueResolver
一起使用时,它失败了。我需要IValueResolver
,因为一些额外的属性不容易映射到SQL结构,例如:
public class Item
{
public int Id { get; set; }
public string Description
{
get { return Convert(DescriptionId); }
set {}
}
public int DescriptionId { get; set; }
}
public string Convert(int value)
{
switch(value)
{
case 1:
return "1";
default:
return "0";
}
}
我也查看了下面的代码,但这与System.ArgumentException: 'Cannot apply ODataQueryOptions of 'DtoItem' to IQueryable of 'Item'. Parameter name: query'
失败了。反转我设法获得结果的数据类型,但我当然无法返回,因为数据类型与我的控制器功能不匹配。但是我确实需要ODataQueryOptions
DtoItem
,否则我将无法访问$ select任何这些额外字段,因为它不会知道它们。但后来我回过头来讨论OData如何将这些选项应用于不同类型的项目。
public IQueryable<Item> Get(ODataQueryOptions queryOptions)
{
IQueryable<Item> items = (IQueryable<Item>) queryOptions.ApplyTo(repositoryItem.Select());
return mapper.Map<List<DtoItem>>(items.ToList()).AsQueryable(); // Cannot convert DtoItem to Item but of course I want to return DtoItem
}
完成此要求对我来说有什么必要?我已经研究过实体框架,但它似乎非常密切。我甚至不确定修改表达式树是否足够。我仍然需要在实现过程中以某种方式添加值。