использование включения в DbSet ef core

#c# #generics #.net-core #entity-framework-core

#c# #общие #.net-ядро #сущность-фреймворк-ядро

Вопрос:

У меня есть несколько классов, все из которых имеют IEnumerable типа File . но я изо всех сил пытаюсь использовать включение с DbSet

  public class FileRepository<T> : IFileRepository<T> where T : class
    {
        private readonly DataContext context;
        private readonly DbSet<T> table = null;

        public FileRepository(DataContext ctx)
        {
            context = ctx;
            table = context.Set<T>();
        }

        public async Task<object> GetByIdAsync(long id)
        {
            if (id > 0)
            {
                return (await table
                  .Include(x => x.Files)
                  .FirstAsync(x => x.Id == id)
                  .ConfigureAwait(false))
                  .Files.ToList();
            }
            else
            {
                return new List<File>();
            }
        }

         
    }
 

Серьезность Описание кода Состояние подавления строки файла проекта
Ошибка CS1061 ‘T’ не содержит определения для ‘Files’ и нет
доступного метода расширения ‘Files’, принимающего первый аргумент типа
Может быть найден ‘T’ (вам не хватает директивы using или
ссылки на сборку?)

Ответ №1:

РЕДАКТИРОВАТЬ Вы пытаетесь написать код для определенной службы, это универсальный. Вам нужно добавить ограничения на T.

например, T является общим, поэтому нет способа узнать, что есть свойство. Идентификатор или файлы там, напишите свою логику на уровне выше.

 public class EmployeeFiles<Employee> : IFileRepository<Employee>
{
    //... Write your logic here instead so the logic is specific to the Entity.
}
 

В качестве альтернативы вы можете заставить все объекты, которые вы хотите реализовать в file api, реализовать inteface

  public interface IHasFileProperties
 {
      public int Id {get; set;}
      public ICollection<File> Files { get; set; }
 }
 

и иметь файловое хранилище:

   IFileRepository<T> where T : IHasFileProperties
 

Кроме того, из представленной вами проблемы GetById должен возвращать T, а не список файлов, если вы хотите получить список файлов, вы должны создать расширение в своем существующем репозитории.

Примечание: ASP.Net-core избавился от устаревшего контекста синхронизации, поэтому вам больше не нужно вызывать .ConfigureAwait(false)) , если вы не используете библиотеку, ориентированную на более старую .net 4.5 или приложения с пользовательским интерфейсом. Смотрите Этот блог Стивена Клири для получения полной информации, для краткого обзора прочитайте комментарии, оставленные@IvanStoev

Комментарии:

1. ни один из них, похоже, не работает, пробовал несколько разных перестановок, и все это привело к тому, что какой-то T не содержит определения для чего бы то ни было

2. Упс, извините, теперь я вижу вашу проблему. Дайте мне секунду для редактирования

3. Чтобы упростить мой ответ, вы пытаетесь написать конкретный код в общем репозитории, вы должны просто использовать репозиторий, откуда он вам нужен, а затем получить список файлов из T.

4. Так что это просто ASP.NET Ядро, как я и думал. Обратите внимание, что он написал «Любой код, который знает, что он выполняется под ASP.NET Ядру не нужно явно избегать его контекста «.. А также «Тем не менее, я по-прежнему рекомендую вам использовать его в своих основных библиотеках — все, что может быть повторно использовано в других приложениях. Если у вас есть код в библиотеке, который также может выполняться в приложении пользовательского интерфейса или устаревшем ASP.NET app или где-либо еще может быть контекст, тогда вы все равно должны использовать ConfigureAwait(false) в этой библиотеке «. В любом случае, спасибо за разъяснение, мне было любопытно, не пропустил ли я что-то вобщие сведения .NET 🙂 Приветствия.

5. Консоль @johnny5, WinForms (! :-)), WPF, UWP, Xamarin (? — не уверен) — есть еще много не ASP.NET Приложения основного типа. Насколько я понимаю, концепция пользовательского контекста синхронизации по-прежнему сохраняется, и async / await по-прежнему использует ее там, где она реализована. Если нет пользовательской реализации (например, в ASP.NET Core), по умолчанию для возобновления используется пул потоков, что является тем же поведением, что и принудительное .ConfigureAwait(false) .