Реализация универсального сервиса DbContext - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть универсальный интерфейс, который я хочу реализовать в своем коде со всех сторон, хотя реализация может отличаться на некотором уровне наследования. Почему я делаю это, потому что я пишу этот код для каждого отдельного проекта, который я делаюи мне надоело писать один и тот же код с небольшими изменениями или без них все время.

Я создал этот интерфейс:

/// <summary>
// A generic interface for implementing the basic database operations.
// This interface can easily be implemented with custom user logic.
// The KId generic parameter is the primary key of the associated entity and the TEntity
// refers to the entity type.
// </summary>
// <typeparam name = "K" > The primary key of the entity.</typeparam>
// <typeparam name = "TEntity" > The type of entity.</typeparam>
public interface IGenericEntity<K, TEntity>
{
    // ........Definition codes...............
}

Хотя я могу реализовать это во всех моих реализациях службыклассы на разных уровнях, но я могу писать некоторые вещи, которые одинаковы в других реализациях службы.

Теперь я решил создать этот класс с именем GenericEntityImplementation, который я буду реализовывать в IGenericEntity.

    public class GenericEntityImplementation<K, TEntity, TDbContext> : 
        IGenericEntity<K, TEntity> where TDbContext : DbContext
    {
        private readonly TDbContext _DbContext;

        public GenericEntityImplementation(TDbContext DbContext)
        {
            _DbContext = DbContext;
        }

/*1 */  public virtual async Task<OperationResult> DeleteAsync(Expression<Func<TEntity, bool>> expression)
/*2 */  {
/*3 */      Task TaskResult = await _DbContext.Set<TEntity>().RemoveRange<TEntity>(expression);
/*4 */      if (TaskResult.Status == TaskStatus.RanToCompletion)
/*5 */      {
/*6 */          return new OperationResult()
/*7 */          {
/*8 */              Message = "",
/*9 */              ReturnObject = null,
/*10*/              Status = OperationStatus.Deleted,
/*11*/              Succeeded = true
/*12*/          };
/*13*/      }
/*14*/  }
    }

K - это тип ключа
TEntity может быть классом базы данных или, скорее, таблицей базы данных, подлежащей скаффолдингу
TDbContext имеет тип DbContext, как видно выше.

Как видно выше, я передал виртуальный DbContext в класс, который я хочу выполнять все операции с базой данных на этом уровне.Я пытался, но, как видно из строки 3, редактор показывает мне, что у моего кода есть некоторые проблемы (подчеркнут красным).

Мой вопрос: может ли кто-нибудь объяснить мне, как я могу сказатьDbContext передал классу тип сущности, на которую я пытаюсь ссылаться в любом случае, как я могу сделать в приведенном ниже коде?

public class ViewDbContext : IdentityDbContext
{
    public HotelDbContext(DbContextOptions<HotelDbContext> options) : base(options)
    {
    }

    public DbSet<View> Views { get; set; }
}


public class ViewsService
{
    private readonly ViewDbContext _DbContext;

    public GenericEntityImplementation(ViewDbContext DbContext)
    {
        _DbContext = DbContext;
    }

    public virtual bool Any()
    {
        return _DbContext.Views.Any() ? true : false;
    }
}

1 Ответ

0 голосов
/ 21 сентября 2019

Как было сказано выше, ошибка, которую я получал в редакторе, была следующей: «TEntity» должен быть ссылочным типом, чтобы использовать его в качестве параметра «TEntity» в универсальном типе или методе «DbContext.Set ()».Но после этого что-то вспыхнуло в моей голове, и я включил эту строку вверху, и теперь все работает отлично.where TEntity : class

public class GenericEntityImplementation<K, TEntity, TDbContext> : 
        IGenericEntity<K, TEntity> where TDbContext : DbContext where TEntity : class
{
}
...