Оптимизация производительности для LINQ к SQL


Я работаю с C# в течение некоторого времени, но относительно новым понятиям лямбда-выражений и LINQ. Я работаю с LINQ к SQL пример и пытаюсь написать общее решение для выполнения поиска по коллекции объектов (например. список клиентов объектов), где искать параметр будет уточняться путем передачи, частично заполненный объект класса Entity себя. Я делаю это просто, чтобы убедиться, что человек не должен идти на указание различных перегрузок для различных поисков на основе атрибутов сущности класса и пытаюсь написать универсальное решение, которое будет удовлетворять любого класса сущности.

Поэтому я использовал отражение и множества предикатов последовательно применять предложение where для коллекции.

Клиентское Приложение

using (CustomerManager oCustomerManager = new CustomerManager())
{
   IEnumerable<Customer> customers = oCustomerManager.Load();

   Customer oSearchCustomer = new Customer();
   oSearchCustomer.City = "London";
   oSearchCustomer.ContactName = "Thomas Hardy";

   IEnumerable<Customer> customerList = oCustomerManager.Search(oSearchCustomer);

   foreach (Customer customer in customerList)
   {
      Console.WriteLine(customer.ToString());
   }
}

Класса Менеджер

public IEnumerable<Customer> Search(Customer searchObject)
{
    IEnumerable<Customer> customers = DataContext.Customers;
    List<Func<Customer, bool>> result = 

    DataContext.Customers.GenerateFilterClause<Customer>(searchObject);

    foreach (var item in result)
    {
        customers = customers.Where(item);
    }

    return customers;
 }

Метод Расширения Служебный Класс

public static class UtilityExtensions
{
   public static List<Func<T, bool>> GenerateFilterClause<T>(this IEnumerable<T> 
          collection, T searchEntity)
   {
        List<Func<T, bool>> whereFilterList = new List<Func<T, bool>>();
        Func<T, bool> predicate = null;

        var propertyList = searchEntity.GetType().GetProperties();

        foreach (PropertyInfo p in propertyList)
        {
            if (p.GetCustomAttributes(false).OfType<ColumnAttribute>().Count() > 0)
            {
               string propName = p.Name;
               var searchVal = 

               searchEntity.GetType().GetProperty(propName).GetValue(searchEntity,null);
               if (searchVal != null)
               {
                  predicate = new Func<T, bool>(entity => propertyWhereClause(entity, 
                         searchEntity, propName, searchVal));
                  whereFilterList.Add(predicate);
               }
            }
         }

         return whereFilterList;
     }

      private static bool propertyWhereClause<T>(T obj, T searchEntity, string    propertyName, object searchVal)
     {
           return obj.GetType().GetProperty(propertyName).GetValue(obj, 
                                   null).Equals(searchVal);
      }
  }

В то время как решение работает, у меня два конкретных вопроса:

  • Каковы недостатки этого решения? Я надеялся иметь входы относительно производительности и чище способ, чтобы переписать код.
  • Может кто-нибудь подскажет более эффективное и лучшее решение? Что бы помочь мне понять, как правильно использовать силу лямбды и LINQ.


1073
6
задан 29 апреля 2011 в 05:04 Источник Поделиться
Комментарии
1 ответ

Сколько вы смотрите в LINQ к SQL? Если у вас нет причин не выставить значение DataContext, вы можете просто выполнять запросы без использования 'поиск объектов'.

from c in DataContext.Customers
where c.City == "London" && c.ContactName == "Thomas Hardy"
select c

Я не использовал LINQ в SQL сам, поэтому я не могу действительно сказать много о лучших практик и Ли или не подвергая класс DataContext - это хорошая идея. Наверное, лучше использовать существующую рамках ОРМ. DataObjects.NET выглядит очень красиво.

Хороший ОРМ обзор можно найти на ORMbattle.

3
ответ дан 29 апреля 2011 в 10:04 Источник Поделиться