Entity Framework с производительностью Linq to Entities - PullRequest
0 голосов
/ 14 мая 2010

Если у меня есть такой статический метод

    private static bool TicArticleExists(string supplierIdent)
    {
        using (TicDatabaseEntities db = new TicDatabaseEntities())
        {
            if((from a in db.Articles where a.SupplierArticleID.Equals(supplierIdent) select a).Count() > 0)
                return true;                
        }
        return false;
    }

и использовать этот метод в различных местах в циклах foreach или просто вызывать его много раз, создает ли он и открывает ли новое соединение каждый раз?

  1. Если так, как я могу справиться с этим? Должен ли я где-нибудь кэшировать результаты, как в этом случае, я бы кэшировал всю таблицу классификаций в кэше памяти? И затем запросы против этого кэшированного объекта?
  2. Или я должен сделать переменную TicDatabaseEntities статической и инициализировать ее на уровне класса?
  3. Должен ли мой класс быть статическим, если он содержит только статические методы? Потому что сейчас это не ..
  4. Также я заметил, что если я возвращаю result.First () вместо FirstOrDefault () и запрос не найдет совпадение, он выдаст исключение (с FirstOrDefault () исключения нет, он возвращает ноль) .

Спасибо за разъяснения.

Ответы [ 4 ]

1 голос
/ 14 мая 2010
  • новые соединения не дорогие благодаря кэшированию соединений. По сути, он захватывает уже открытое соединение (я думаю, что они остаются открытыми в течение 2 минут для повторного использования).

  • Тем не менее, кэширование может быть лучше. Мне действительно не нравится "firstordefault". Думает о том, можете ли вы на самом деле добавить больше в ОДНОМ утверждении, а затем работать с этим.

В остальном я ничего не могу сказать - слишком многое зависит от того, что вы на самом деле там делаете логически. Что такое TicDatabaseEntities? МОЖЕТ ли это быть кэшировано? Сколько? То же самое с (3) - мы не знаем, потому что мы не знаем, что там еще.

Если это что-то вроде получения нескольких строк поиска для последующего использования, я бы сказал ...

  • Создание ключа из класса I, класса II, класса III
  • загрузить все классификации в (я предполагаю, что есть только пара сотен)
  • Поместите их в статический / кэшированный словарь, предполагая, что они обычно не меняются (и я думаю, у меня есть эта идея здесь - это финансовая база данных тикстрима?)

Без знания бизнеса на это невозможно ответить.

4: да, это так, как задокументировано. First дает первое или исключение, по умолчанию FirstOrDefault по умолчанию (пустая структура, инициализированная 0, нуль для классов).

0 голосов
/ 14 мая 2010

Я пытаюсь найти статью, где я прочитал это, но я думаю, что лучше сделать (если вы просто ищете счет):

from a in db.Articles where a.SupplierArticleID.Equals(supplierIdent) select 1

Также используйте Any вместо Count> 0.

Обновится, когда я смогу процитировать источник.

0 голосов
/ 14 мая 2010

это создает и открывает новое соединение каждый раз?

Нет. Соединения кэшируются.

Должен ли я где-нибудь кешировать результаты

Нет. Не кэшируйте целые таблицы.

я должен сделать переменную TicDatabaseEntities статической и инициализировать ее на уровне класса?

Нет. Не сохраняйте экземпляр DataContext дольше, чем UnitOfWork.

Должен ли мой класс быть статическим, если он содержит только статические методы?

Конечно ... это не позволит никому создавать бесполезные экземпляры класса.

Также я заметил, что если я верну result.First () вместо FirstOrDefault () и запрос не найдет совпадение, он выдаст исключение

Таково поведение Первого. Поэтому я обычно ограничиваю использование First для IGroupings или для коллекций, ранее проверенных с помощью .Any ().


Я бы переписал ваш существующий метод как:

using (TicDatabaseEntities db = new TicDatabaseEntities()) 
{
  bool result = db.Articles
    .Any(a => a.supplierArticleID.Equals(supplierIdent));

  return result;
}

Если вы вызываете метод в цикле, я бы переписал:

private static Dictionary<string, bool> TicArticleExists
  (List<string> supplierIdents)   
{
  using (TicDatabaseEntities db = new TicDatabaseEntities())   
  {   
    HashSet<string> queryResult = new HashSet(db.Articles
      .Where(a => supplierIdents.Contains(a.supplierArticleID))
      .Select(a => a.supplierArticleID));

    Dictionary<string, bool> result = supplierIdents
      .ToDictionary(s => s, s => queryResult.Contains(s));

    return result;
  }
}
0 голосов
/ 14 мая 2010

Спасибо, Дэн и TomTom, я придумал это. Не могли бы вы прокомментировать это, если вы видите что-нибудь или заказ?

    public static IEnumerable<Article> TicArticles
    {
        get
        {
            ObjectCache cache = MemoryCache.Default;
            if (cache["TicArticles"] == null)
            {
                CacheItemPolicy policy = new CacheItemPolicy();
                using(TicDatabaseEntities db = new TicDatabaseEntities())
                {
                    IEnumerable<Article> articles = (from a in db.Articles select a).ToList();
                    cache.Set("TicArticles", articles, policy);
                }
            }

            return (IEnumerable<Article>)MemoryCache.Default["TicArticles"];
        }
    }


    private static bool TicArticleExists(string supplierIdent)
    {
        if (TicArticles.Count(p => p.SupplierArticleID.Equals(supplierIdent)) > 0)
            return true;
        return false;
    }

Если это нормально, я заставлю все мои методы следовать этому шаблону.

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