Итак, прежде всего, если вы следуете соглашениям по именованию, вам не нужно явно использовать атрибуты.Key
атрибут может быть безопасно удален.Атрибут ForeignKey
можно удалить, если вы измените имя свойства на множественное число: Contacts
и Addresses
.Я настоятельно рекомендую вам использовать единичные имена для классов и множественные имена для свойств навигации по коллекциям (например, в отношении «один ко многим»).
// Contact is name of class, plural name for property: Contacts
public ICollection<Contact> Contacts { get; set; }
Если вы используете OData, вы должны создать свою Модель EDM (которую вы нам не показали).Также не используйте хранимые процедуры для простого SELECT
, если у вас есть доступ к DbContext
.Вся логика вашего контроллера не нужна и может быть заменена следующим образом:
[EnableQuery]
public IQueryable<Customer> GetAllCustomers()
{
return db.Customers;
}
Таким образом, в коде это может выглядеть следующим образом:
Класс клиента
public class Customer
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string VatCode { get; set; }
public string ChamberOfCommerceCode { get; set; }
public DateTime Modified { get; set; }
public DateTime Created { get; set; }
public string LanguageCode { get; set; }
public decimal Discount { get; set; }
public string CustomerManager { get; set; }
public Guid PriceList { get; set; }
public Guid PaymentCondition { get; set; }
public bool IsBlocked { get; set; }
public bool IsProspect { get; set; }
public bool IsSuspect { get; set; }
public string Website { get; set; }
public string DashboardUrl { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Fax { get; set; }
public ICollection<FreeFields> FreeFields { get; set; }
public ICollection<Contact> Contacts { get; set; }
public ICollection<Address> Addresses { get; set; }
}
Класс контакта
public class Contact
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Initials { get; set; }
public string Function { get; set; }
public Guid Customer { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
public string LanguageCode { get; set; }
public bool IsMainContact { get; set; }
public string Gender { get; set; }
public string Username { get; set; }
public Guid CustomerId { get; set; }
// If you want to use class reference navigation property (also called as "hard reference").
// That can be used in "$expand" or "$select" for example.
// Uncomment the following line:
// public Customer Customer { get; set }
}
Адрес класса
public class Address
{
public Guid Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string PostalCode { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string CountryCode { get; set; }
public string Type { get; set; }
public bool IsMainAddress { get; set; }
public string Route { get; set; }
public string State { get; set; }
public Guid CustomerId { get; set; }
// If you want to use class reference navigation property (also called as "hard reference").
// That can be used in "$expand" or "$select" for example.
// Uncomment the following line:
// public Customer Customer { get; set }
}
Создайте модель EDM:
public class MyModelBuilder
{
public IEdmModel GetEdmModel(IServiceProvider serviceProvider)
{
var builder = new ODataConventionModelBuilder(serviceProvider);
builder.EntitySet<Address>("Addresses")
.EntityType
.Filter() // Allow for the $filter Command
.Count() // Allow for the $count Command
.Expand() // Allow for the $expand Command
.OrderBy() // Allow for the $orderby Command
.Page() // Allow for the $top and $skip Commands
.Select();// Allow for the $select Command;
builder.EntitySet<Contact>("Contacts")
.EntityType
.Filter() // Allow for the $filter Command
.Count() // Allow for the $count Command
.Expand() // Allow for the $expand Command
.OrderBy() // Allow for the $orderby Command
.Page() // Allow for the $top and $skip Commands
.Select() // Allow for the $select Command
.Expand();
builder.EntitySet<Customer>("Customers")
.EntityType
.Filter() // Allow for the $filter Command
.Count() // Allow for the $count Command
.Expand() // Allow for the $expand Command
.OrderBy() // Allow for the $orderby Command
.Page() // Allow for the $top and $skip Commands
.Select() // Allow for the $select Command
.Expand();
return builder.GetEdmModel();
}
}
Используйте его в Запуск :
public void ConfigureServices(IServiceCollection services)
{
// ... Other Configurations
services.AddOData();
services.AddTransient<MyModelBuilder>();
// ... MVC Service Configurations
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, MyModelBuilder modelBuilder)
{
// ... Other Configurations
app.UseMvc(routeBuilder =>
{
routeBuilder.MapODataServiceRoute("ODataRoutes", "odata", modelBuilder.GetEdmModel(app.ApplicationServices));
});
}
И, наконец, создайте контроллер:
[Produces("application/json")]
public class CustomersController : ODataController
{
private readonly MyDbContext _context;
public CustomersController (MyDbContext context) => _context = context;
[EnableQuery]
public IQueryable<Customer> GetAllCustomers() => _context.Customers;
}
(В приведенном выше коде я предполагаю, что вы правильно настроили DbContext
)
Теперь вы сможете использовать $expand
или $select
, чтобы получить, например, все адреса клиентов.
HTTP GET /odata/Customers?$expand=Addresses