Ef core Одата Многие ко многим - PullRequest
0 голосов
/ 02 апреля 2020

Я занимаюсь разработкой Asp. Net Core 2.2 приложения с ODATA. У меня есть тестовое приложение для воспроизведения проблемы: я не могу запросить связанных сущностей с таблицей ссылок через запрос ODATA .

Запрос: / odata / Books? $ Expand = BookCategories

ошибка ответа:

"Message": "The query specified in the URI is not valid. Property 'BookCategories' on type 'GameStorageView.Data.Book' is not a navigation property or complex property. Only navigation properties can be expanded.",
"ExceptionMessage": "Property 'BookCategories' on type 'GameStorageView.Data.Book' is not a navigation property or complex property. Only navigation properties can be expanded.",
"ExceptionType": "Microsoft.OData.ODataException",

модель:

 public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public ICollection<BookCategory> BookCategories { get; set; }
    }

    public class Category
    {
        public int CategoryId { get; set; }
        public string CategoryName { get; set; }
        public ICollection<BookCategory> BookCategories { get; set; }
    }

    public class BookCategory
    {
        public int BookId { get; set; }
        public Book Book { get; set; }
        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }

Создание модели:

modelBuilder.Entity<BookCategory>()
                .HasKey(bc => new {bc.BookId, bc.CategoryId});
            modelBuilder.Entity<BookCategory>()
                .HasOne(bc => bc.Book)
                .WithMany(b => b.BookCategories)
                .HasForeignKey(bc => bc.BookId);
            modelBuilder.Entity<BookCategory>()
                .HasOne(bc => bc.Category)
                .WithMany(c => c.BookCategories)
                .HasForeignKey(bc => bc.CategoryId);

Как заставить это работать? Как запросить сущности «многие ко многим» через оддату?

UPD:

Настроены ODATA: .EntityType.Count().Filter().OrderBy().Expand(SelectExpandType.Allowed,10).Select().Page().Count();

linq-запрос работает нормально: context.Book.Include(c=>c.BookCategories).ToArray()

1 Ответ

0 голосов
/ 03 апреля 2020

Хорошо, мое решение не лучшее, но оно работает: нам нужно добавить поле Id и уникальное ограничение к нему:

public class BookCategory
    {
        public int Id { get; set; }
        public int BookId { get; set; }
        public Book Book { get; set; }
        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }

и

modelBuilder.Entity<BookCategory>().HasAlternateKey(bc => bc.Id);

, а затем, если мы хотим загрузить связанные сущности через оддаты, нам также нужно добавить сущность ссылки в маршруты одататы. Я использую метод расширения, поэтому он выглядит следующим образом:

public static void RegisterOdataRoute<TEntity>(this ODataConventionModelBuilder builder, string name = null, bool pluralize = true) where TEntity : class
        {
            name = name ?? $"{typeof(TEntity).Name}";

            var names = pluralize ? $"{name}s" : name;

            OdataRoutes.Add(name, $"~/odata/{names}");
            builder.EntitySet<TEntity>(names).EntityType.Count().Filter().OrderBy().Expand(SelectExpandType.Allowed,10).Select().Page().Count();
        }
    }

и

app.UseOData(builder =>
            {
                builder.RegisterOdataRoute<BookCategory>();
                    ...

Если кто-то нашел лучшее решение, пожалуйста, дайте мне знать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...