Я занимаюсь разработкой фильтрации для существующего проекта WEB API.Для этого было решено использовать OData.У меня есть базовая инфраструктура (Core EF и DbContext).Кроме того, для веб-API я использую модели DTO этих основных объектов.Все модели DTO имеют аннотации данных.Проблема в том, что фильтрация OData не работает с именами аннотаций данных.Я пытался следовать предложениям из других тем, но потерпел неудачу.Я буду признателен за любые предложения по этой проблеме.
Установлен Microsoft.AspNet.OData 7.2.1.
Основные объекты:
[Serializable]
[DataContract(IsReference = true)]
public class Staff
{
public Staff
{
this.StaffRoles = new HashSet<StaffRole>();
}
[DataMember]
public bool Active { get; set; }
[DataMember]
public int? ContactId { get; set; }
[DataMember]
public bool? ExternalStaff { get; set; }
[DataMember]
public int PrimaryKey { get; set; }
[DataMember]
public string StaffLogin { get; set; }
[DataMember]
public virtual Contact Contact { get; set; }
[DataMember]
public virtual ICollection<StaffRole> StaffRoles { get; set; }
}
[Serializable]
[DataContract(IsReference = true)]
public class Contact
{
public Contact()
{
this.StaffPersons = new HashSet<Staff>();
}
[DataMember]
public string Email { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int PrimaryKey { get; set; }
[DataMember]
public virtual ICollection<Staff> StaffPersons { get; set; }
}
Модель DTO:
[DataContract]
public class StaffDTO
{
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "first_name")]
public string FirstName { get; set; }
[DataMember(Name = "last_name")]
public string LastName { get; set; }
[DataMember(Name = "is_status_active")]
public bool IsStatusActive { get; set; }
[DataMember(Name = "login")]
public string Login { get; set; }
[DataMember(Name = "email")]
public string Email { get; set; }
[DataMember(Name = "is_staff_external")]
public bool IsStaffExternal { get; set; }
[DataMember(Name = "roles")]
public IEnumerable<StaffRoleDTO> StaffRoles { get; set; }
}
WebApiConfig:
var builder = new ODataConventionModelBuilder();
builder.ModelAliasingEnabled = true;
builder.EntitySet<StaffDTO>("Staffs").EntityType.Name= "Staff";
var staffType = builder.EntityType<StaffDTO>();
config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());
config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
Контроллер веб-API:
public class CommonODataController : ODataController
{
private IMapper mapper;
private MyDbContext dbContext;
public CommonODataController(IMapper mapper, MyDbContext dbContext)
{
this.mapper = mapper;
this.dbContext = dbContext;
}
[HttpGet]
[EnableQuery]
public IQueryable<StaffViewModel> GetStaff()
{
IQueryable<Staff> staffQuery = this.dbContext.Staffs
.Include(x => x.Contact)
.Include(x => x.StaffRoles);
var staffDTOQuery = this.mapper.ProjectTo<StaffDTO>(staffQuery);
return staffDTOQuery;
}
}
Конфигурация AutoMapper:
CreateMap<Staff, StaffDTO>()
.ForMember(dst => dst.Id, opts => opts.MapFrom(src => src.PrimaryKey))
.ForMember(dst => dst.FirstName, opts => opts.MapFrom(src => src.Contact.FirstName))
.ForMember(dst => dst.LastName, opts => opts.MapFrom(src => src.Contact.LastName))
.ForMember(dst => dst.IsStatusActive, opts => opts.MapFrom(src => src.Active))
.ForMember(dst => dst.Login, opts => opts.MapFrom(src => src.StaffLogin))
.ForMember(dst => dst.Email, opts => opts.MapFrom(src => src.Contact.Email))
.ForMember(dst => dst.IsStaffExternal, opts => opts.MapFrom(src => src.ExternalStaff))
.ForMember(dst => dst.StaffRoles, opts => opts.MapFrom(src => src.StaffRoles));
Когда я отправляю запрос"... / staff? $ top = 50 & $ filter = first_name eq 'some name'" Я получаю ошибку "Свойство экземпляра 'first_name' не определено для типа 'StaffDTO'}".
Любые идеичто не так?