ContentType
- > EF模型
ContentTypes
- > DTO
在我的OData控制器中:
public Task<IQueryable<ContentTypes>> Get(ODataQueryOptions<ContentTypes> options)
{
var result = options.ApplyTo(_repository.Query().Get()
.Where(u => u.UserId == userId)
.OrderBy(o => o.Description))
.Cast<ContentTypes>();
return result;
}
尝试应用ODataQueryOptions
时收到错误500。由于该类已经继承ODataController
,我甚至需要执行options.ApplyTo(...)
?
答案 0 :(得分:1)
此解决方案是确保返回类型是DTO的类型,并且ODataQueryOptions
应用于EF实体。然后我使用Automapper将结果映射到DTO。
我已根据@Schandlich的建议更新了答案,但有些问题仍然存在:
[Queryable]
public virtual IHttpActionResult Get(ODataQueryOptions<ContentType> options)
{
var userId = 102; // mock
try
{
var results = options.ApplyTo(_uow.Repository<ContentType>()
.Query()
.Get()
.Include(u => u.User)
.Where(u => u.UserId == userId)
.OrderBy(o => o.Description)).Cast<ContentType>()
.Select(x => new ContentTypeDTO()
{
//projection goes here
ContentTypeId = x.ContentTypeId,
Description = x.Description,
UserDTO = new UserDTO
{
UserId = x.UserId,
UserName = x.User.UserName
}
});
return this.Ok(results);
}
catch (Exception ex)
{
throw ex;
}
}
使用ODataQueryOptions
的原因是我希望EF在数据库调用级别处理过滤。否则,我会返回所有记录,然后Queryable
会返回,比如第一页结果。
我删除了Automapper代码,但很好奇为什么不使用它?
正如@Schandlich指出的那样,这不适用于$select
或$expand
。
答案 1 :(得分:0)
根据@ ElHaix的答案进行了更新。我不能更强烈地建议不要使用AutoMapper从这样的数据源进行映射。这也假设在调用数据库之前应用了应用于存储库的查询。
[Queryable]
public virtual IHttpResult Get()
{
var userId = 102; // mock
try
{
var results = _uow.Repository<ContentType>()
.Query()
.Get()
.Where(u => u.UserId == userId)
.OrderBy(o => o.Description)
.Select(x => new ContentTypeDTO()
{
//projection goes here
});
return this.Ok(results);
}
catch (Exception ex)
{
throw ex;
}
}
另外,我会尝试对ElHaix的答案进行$ select。
答案 2 :(得分:0)
我能够通过AutoMapper Project()扩展实现这一目标。 $ select,$ filter等都应用于数据库查询。
[TestMethod]
public void DataShaping_With_AutoMapper_And_OData_Select_Test()
{
OracleMonitor myMonitor = new OracleMonitor();
myMonitor.IsActive = true;
var dbcontext = new MyDbContext();
var datasource = dbcontext.Datasouces;
Assert.IsNotNull(datasource);
SetupAutoMapper();
var odataQuery = Extensions.CreateDummyODataQuery<DataSourceDTO>("$expand=Fields($select=Description)&$select=Name");
var withShaping = datasource.Project().To<DataSourceDTO>();
Assert.IsNotNull(withShaping);
var withODataQuery = odataQuery.ApplyTo(withShaping);
Assert.IsNotNull(withODataQuery);
string strJson = JsonConvert.SerializeObject(withODataQuery);
Assert.IsFalse(String.IsNullOrEmpty(strJson));
}