Вы можете обернуть функций внутри подразделений связи для повторного использования?


Мне было любопытно, какой шаблон повторного использования может быть возможен, и я хотел посмотреть, пробовали ли его другие. По существу, у меня есть такие, например, стандартные возвраты EF 6.1.3:

private IEnumerable<TypeTran> GetTypes()
{
  using (var context = new ExpensesEntities())
  {
    return context.tdType.Select(x => new TypeTran(x.TypeID, x.Description)).Where(x => x.TypeId != 3);
  }
}

private List<Category> GetCurrentCategories()
{
  using (var context = new ExpensesEntities())
  {
    return context.tdCategory.Select(x => new Category(x.CategoryID, x.Description)).ToList();
  }
}

На самом деле не беспокойтесь о TypeTran или категории. Достаточно сказать, что они просто POCOs и могут быть чем угодно. Они просто абстрагируют удаление слоя EF, чтобы я мог иметь больше эффектов после рынка на объект модели, не влияя на созданные объекты T4 из базы данных. Эта модель работает отлично, но существует гораздо больше шаблонов поиска, поэтому мне было любопытно, могу ли я сделать что-то вроде:

private TReturn RunContextWithOption<TReturn>(Func<ExpensesEntities, TReturn> func)
{
  using (var context = new ExpensesEntities())
  {
    return func.Invoke(context);
  }
}

Но когда я пытаюсь запустить его, я делаю синтаксис неправильно, и я также не вижу способа использовать контекст без предварительного определения его.

//Wrong won't run
private List<TypeTran> GetTypes()
{
  var cont = new ExpensesEntities();
  return RunContextWithOption<List<TypeTran>>((cont) => cont.tdType.Select(x => new TypeTran(x.TypeID, x.Description)).Where(x => x.TypeId != 3));

}

Таким образом, он становится курицей или яйцом, я хочу, чтобы контекст автоматически вызывался с помощником, но я не могу, так как мне нужно, чтобы в arg он появился. Кто-нибудь еще пробовал что-то подобное, чтобы сделать свой шаблон РЕПО просто меньшим количеством строк кода? Этот может быть, это плохая практика, но я обычно за меньшее количество строк кода и использую частные помощники, когда это возможно, а не повторяю использование (VAR context...) до бесконечности.

1 2

1 ответ:

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

public IEnumerable<TEntity> GetEntities<TEntity>(
    Expression<Func<TEntity, bool>> predicate = null)
    where TEntity : class
{
    using (var context = new ExpensesEntities())
    {
        IQueryable<TEntity> data = context.Set<TEntity>();
        if (predicate != null)
        {
            data = data.Where(predicate);
        }

        return data.ToList();
    }
}

И назовем это так:

var diedOn = DateTime.Now.AddDays(-30);
var zombiesOlderThan30Days = GetEntities<Zombie>(z => 
    z.Name == "Bob" && z.DiedOn > diedOn);

var allZombies = GetnEntities<Zombie>();