Повторное использование интерфейса DbContext без множественного наследования

81
8

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

 public interface IMyDbContext : IDisposable
{
IDbSet<Reference_CountryModel> Reference_Country { get; set; }
List<UspGetCountryListReturnDto> UspGetCountryList(out int aProcResult);
List<UspGetBrandByWebsiteListReturnDto> UspGetBrandByWebsiteList(DbContext aDbContext, short? aWebsiteId, out int aProcResult)
}

Поэтому давайте предположим, что мой первый контекст БД:

public class MyFirstDbContext : DbContext, IMyDbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new Reference_CountryConfiguration());
}

public IDbSet<Reference_CountryModel> Reference_Country { get; set; }
public List<UspGetCountryListReturnDto> UspGetCountryList(out int aProcResult)
{
SqlParameter procResultParam = new SqlParameter {ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output};

List<UspGetCountryListReturnDto> procResultData = Database.SqlQuery<UspGetCountryListReturnDto>("EXEC @procResult = [dbo].[usp_GetCountryList] ", procResultParam).ToList();

aProcResult = (int) procResultParam.Value;
return procResultData;
}

public List<UspGetBrandByWebsiteListReturnDto> UspGetBrandByWebsiteList(DbContext aDbContext, short? aWebsiteId, out int aProcResult)
{
SqlParameter websiteIdParam = new SqlParameter {ParameterName = "@WebsiteID", SqlDbType = SqlDbType.SmallInt, Direction = ParameterDirection.Input, Value = aWebsiteId.GetValueOrDefault()};
SqlParameter procResultParam = new SqlParameter {ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output};

List<UspGetBrandByWebsiteListReturnDto> procResultData =
aDbContext.Database.SqlQuery<UspGetBrandByWebsiteListReturnDto>("EXEC @procResult = [dbo].[usp_GetBrandByWebsiteList] @WebsiteID", websiteIdParam, procResultParam).ToList();

aProcResult = (int) procResultParam.Value;
return procResultData;
}
}

и мой второй контекст данных (AbpDbContext спускается из DbContext):

public class MySecondDbContext : AbpDbContext, IMyDbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new Reference_CountryConfiguration());
}

public IDbSet<Reference_CountryModel> Reference_Country { get; set; }
public List<UspGetCountryListReturnDto> UspGetCountryList(out int aProcResult)
{
SqlParameter procResultParam = new SqlParameter {ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output};

List<UspGetCountryListReturnDto> procResultData = Database.SqlQuery<UspGetCountryListReturnDto>("EXEC @procResult = [dbo].[usp_GetCountryList] ", procResultParam).ToList();

aProcResult = (int) procResultParam.Value;
return procResultData;
}
public List<UspGetBrandByWebsiteListReturnDto> UspGetBrandByWebsiteList(DbContext aDbContext, short? aWebsiteId, out int aProcResult)
{
SqlParameter websiteIdParam = new SqlParameter {ParameterName = "@WebsiteID", SqlDbType = SqlDbType.SmallInt, Direction = ParameterDirection.Input, Value = aWebsiteId.GetValueOrDefault()};
SqlParameter procResultParam = new SqlParameter {ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output};

List<UspGetBrandByWebsiteListReturnDto> procResultData =
aDbContext.Database.SqlQuery<UspGetBrandByWebsiteListReturnDto>("EXEC @procResult = [dbo].[usp_GetBrandByWebsiteList] @WebsiteID", websiteIdParam, procResultParam).ToList();

aProcResult = (int) procResultParam.Value;
return procResultData;
}
}

}

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

public static class MyDbContextHelper
{

public static void ModelCreating(DbModelBuilder aModelBuilder)
{
aModelBuilder.Configurations.Add(new Reference_CountryConfiguration());
}

public static List<UspGetBrandByWebsiteListReturnDto> UspGetBrandByWebsiteList(DbContext aDbContext, short? aWebsiteId, out int aProcResult)
{
SqlParameter websiteIdParam = new SqlParameter {ParameterName = "@WebsiteID", SqlDbType = SqlDbType.SmallInt, Direction = ParameterDirection.Input, Value = aWebsiteId.GetValueOrDefault()};
SqlParameter procResultParam = new SqlParameter {ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output};

List<UspGetBrandByWebsiteListReturnDto> procResultData =
aDbContext.Database.SqlQuery<UspGetBrandByWebsiteListReturnDto>("EXEC @procResult = [dbo].[usp_GetBrandByWebsiteList] @WebsiteID", websiteIdParam, procResultParam).ToList();

aProcResult = (int) procResultParam.Value;
return procResultData;
}

public List<UspGetCountryListReturnDto> UspGetCountryList(out int aProcResult)
{
SqlParameter procResultParam = new SqlParameter {ParameterName = "@procResult", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Output};

List<UspGetCountryListReturnDto> procResultData = Database.SqlQuery<UspGetCountryListReturnDto>("EXEC @procResult = [dbo].[usp_GetCountryList] ", procResultParam).ToList();

aProcResult = (int) procResultParam.Value;
return procResultData;
}

а затем изменить классы, которые реализуют IMyDbContext, чтобы:

public class MyFirstDbContext : DbContext, IMyDbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
MyDbContextHelper.ModelCreating(modelBuilder);
}

public IDbSet<Reference_CountryModel> Reference_Country { get; set; }
public List<UspGetCountryListReturnDto> UspGetCountryList(out int aProcResult)
{
return MyDbContextHelper.UspGetCountryList(this, aProcResult);
}
}

В верхней части реализация реализована только для MyDbContextHelper.

С другой стороны, для каждого класса, который реализует IMyDbContext и изменения интерфейса, мне все равно нужно:

Когда добавлен набор данных: добавьте свойства IDbSet <> При добавлении нового метода: внедрить метод в помощнике, добавить метод stub для вызова помощника

Я не вижу никакого способа уйти от 1. и 2.? Кто-нибудь получил какие-либо уточнения или предложения, которые еще больше уменьшили бы объем кода, который должен быть записан при изменении интерфейса IMyDbContext? Может ли кто-нибудь увидеть какие-либо проблемы с вышеуказанным подходом?

спросил(а) 2015-06-22T04:35:00+03:00 5 лет, 4 месяца назад
0
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема