Как Вы реализуете шаблон Каналов и Фильтров с LinqToSQL/Entity Framework/NHibernate?

Попробуйте шаблон глобуса, чтобы справиться с непоследовательной нумерацией, и дополните PTS уставками, чтобы наложение не использовалось до его отображения:

ffmpeg -y -i input.mp4 -pattern_type glob -i "1/*.png" -pattern_type glob -i "2/*.png" -filter_complex "[0][1]overlay=x=10:y=10:enable='between(t,0,3)'[v1];[2]setpts=PTS+3.856/TB[fg];[v1][fg]overlay=x=10:y=10:enable='between(t,3.8561422222222,6.9761777777778)'[v2]" -map "[v2]" -map 0:a out.mp4
5
задан Perpetualcoder 24 March 2009 в 20:02
поделиться

1 ответ

В конечном счете, LINQ на IEnumerable<T> каналы и фильтруют реализацию. IEnumerable<T> потоковый API - подразумевать, что данные являются лениво возвратами, как Вы просите их (через блоки итератора), вместо того, чтобы загрузить все сразу и возвратить большой буфер записей.

Это означает что Ваш запрос:

var qry = from row in source // IEnumerable<T>
          where row.Foo == "abc"
          select new {row.ID, row.Name};

:

var qry = source.Where(row => row.Foo == "abc")
            .Select(row = > new {row.ID, row.Name});

поскольку Вы перечисляете по этому, это использует данные лениво. Вы видите это графически с Визуальным LINQ Jon Skeet. Единственными вещами, которые повреждают канал, являются вещи та буферизация силы; OrderBy, GroupBy, и т.д. Для работы большого объема, Jon и я работали над, Требуют у LINQ то, что он сделал, агрегируется, не буферизуя в таких сценариях.

IQueryable<T> (выставленный большинством инструментов ORM - LINQ-SQL, Платформа Объекта, LINQ-to-NHibernate), немного отличающийся зверь; потому что механизм базы данных собирается сделать большую часть тяжелого подъема, возможности состоят в том, что большинство шагов уже сделано - все, что оставляют, должен использовать IDataReader и проект это к объектам/значениям - но это - все еще обычно канал (IQueryable<T> реализации IEnumerable<T>) если Вы не звоните .ToArray(), .ToList() и т.д.

Относительно использования на предприятии... мое представление состоит в том, что хорошо использовать IQueryable<T> для записи компонуемых запросов в репозитории но они не должны покидать репозиторий - поскольку это сделает внутреннюю операцию репозитория подвергающейся вызывающей стороне, таким образом, Вы были бы неспособны к правильно модульному тесту / профиль / оптимизирует / и т.д. Я взял к выполнению умных вещей в репозитории, но списков/массивов возврата. Это также означает, что мой репозиторий остается не знающий о реализации.

Это - позор - как искушение "возвратиться" IQueryable<T> из репозитория метод является довольно большим; например, это позволило бы вызывающей стороне добавлять подкачку страниц/фильтры/и т.д. - но помнить, что они еще на самом деле не использовали данные. Это делает управление ресурсами болью. Кроме того, в MVC и т.д. необходимо было бы удостовериться, что контроллер звонит .ToList() или подобный, так, чтобы это не было представление, которое управляет доступом к данным (иначе, снова, Вы не можете модульный тест контроллер правильно).

Безопасное использование (IMO) просачивается, DAL был бы вещами как:

public Customer[] List(string name, string countryCode) {
     using(var ctx = new CustomerDataContext()) {
         IQueryable<Customer> qry = ctx.Customers.Where(x=>x.IsOpen);
         if(!string.IsNullOrEmpty(name)) {
             qry = qry.Where(cust => cust.Name.Contains(name));
         }
         if(!string.IsNullOrEmpty(countryCode)) {
             qry = qry.Where(cust => cust.CountryCode == countryCode);
         }
         return qry.ToArray();
     }
}

Здесь мы добавили фильтры на лету, но ничего не происходит, пока мы не звоним ToArray. На данном этапе данные получены и возвращены (расположение контекста данных в процессе). Это может быть полностью протестированной единицей. Если мы сделали что-то подобное, но просто возвращенный IQueryable<T>, вызывающая сторона могла бы сделать что-то как:

 var custs = customerRepository.GetCustomers()
       .Where(x=>SomeUnmappedFunction(x));

И внезапно наш DAL начинает перестать работать (не может перевести SomeUnmappedFunction к TSQL, и т.д.). Можно все еще сделать много интересных вещей в репозитории, все же.

Единственная болевая точка здесь - то, что это могло бы продвинуть Вас иметь несколько перегрузок для поддержки различных шаблонов вызова (с/без подкачкой страниц, и т.д.). До дополнительных/именованных параметров прибывает, я нахожу, что лучший ответ здесь должен использовать дополнительные методы в интерфейсе; тем путем мне только нужна одна конкретная реализация репозитория:

class CustomerRepository {
    public Customer[] List(
        string name, string countryCode,
        int? pageSize, int? pageNumber) {...}
}
interface ICustomerRepository {
    Customer[] List(
        string name, string countryCode,
        int? pageSize, int? pageNumber);
}
static class CustomerRepositoryExtensions {
    public static Customer[] List(
          this ICustomerRepository repo,
          string name, string countryCode) {
       return repo.List(name, countryCode, null, null); 
    }
}

Теперь у нас есть виртуальные перегрузки (как дополнительные методы) на ICustomerRepository - таким образом, наша вызывающая сторона может использовать repo.List("abc","def") не имея необходимость указывать подкачку страниц.


Наконец - без LINQ, с помощью каналов и фильтров становится намного более болезненным. Вы будете писать некоторый основанный на тексте запрос (TSQL, ESQL, HQL). Можно, очевидно, добавить строки, но это не очень "канал/фильтр" - выход. "Критерии API" немного лучше - но не так изящны как LINQ.

11
ответ дан 13 December 2019 в 19:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: