• Как получить значение ParameterExpression?

    @iRumba Автор вопроса
    Они никак не отменят дублирование. К тому же уже много запросов со спецификациями, поздно переобуваться.
  • Как получить значение ParameterExpression?

    @iRumba Автор вопроса
    Вот вам синтетический пример.

    У нас есть блог, в нем есть статьи, у статей есть комментарии. Блоги и комментарии привязаны к автору.

    Пользователи могут находиться в бане.

    Нужно построить 3 запроса: список забаненных пользователей (для админки), ленту статей, комментарии к статье.

    В ленте статей не должны отображаться статьи забаненных пользователей. В статье комментарии от забаненных пользователей тоже должны фильтроваться. Для упрощения я буду писать запросы без сортировки, материализации и других лишних деталей.

    var bannedUsers = ctx.Users.Where(x => x.IsBanned);
    
    var postsLine = ctx.Posts.Where(x => !x.Blog.Author.IsBanned);
    
    var comments = ctx.Comments.Where(x => x.Post.Id == postId && !x.Author.IsBanned);


    Вот смотрите, во всех трех запросах используется одно и то же условие, забанен ли пользователь. Я не люблю подобное дублирование. И дело тут не только в эстетике. Завтра мне потребуется изменить механизм бана и вместо флага будет таблица банов (с датой начала и датой окончания). Придется лазить по всем местам, где используется это условие и менять. К тому же, если для банов будет таблица, проверка на бан будет несколько сложнее, чем с флагом, а значит будет шанс в каком-нибудь из запросов допустить ошибку, которая всплывет только в проде спустя какое то время (все зависит от наличия/качества автоматических тестов и ручного тестирования).

    Поэтому, условие того, что пользователь забанен лучше хранить отдельно. Но как его использовать в трех этих запросах? Тут придется найти методы расширения для лямбда выражений (или написать самому), чтобы иметь возможность комбинировать предикаты. predicate1.And(predicate2).

    Но тогда появится еще одна проблема. Предикат для забаненных пользователей имеет входящий тип User. А в этом запросе var postsLine = ctx.Posts.Where(x => !x.Blog.Author.IsBanned); входящий тип Post. В итоге, после всех магических финтов с выражениями (на более серьезных запросах), запрос может стать не очень выразительным. А некоторые условия вообще требуют параметры (идентификатор, дата и другие).

    Наши изыскания привели нас к библиотеке NSpecification, которая реализует паттерн спецификация и содержит в себе тип Specification. Тип этот имеет свойство типа LambdaExpression (конечно же дженерик) и позволяет применять к спецификациям логические операции & |. Это позволяет делать такие финты, которые с чистыми Expression не сделать. Например, можно состряпать новую спецификацию на основе двух других с синтаксисом spec1 & spec2. Это удовольствие сомнительное, но это не единственная плюха.

    Еще есть неявное приведение к Expression.

    Есть у них полезные функции. Например, метод расширения для Object функция Is.

    public static bool Is(this object obj, Specification spec)


    Это позволяет выполнять такие штуки theUser.Is(banned). То есть запрос на получение комментов мог выглядеть как то так.

    var commentsByPostSpecification = new CommentsByPostSpecification(postId);
    var commentsWithoutBannedSpecification = new Specification<Comment>(x => x.Author.Is(new BannedUserSpecification()));
    
    var comments = ctx.Comments.Where(commentsByPostSpecification & commentsWithoutBannedSpecification);


    Все прозрачно, каждую хранимую спецификацию можно покрыть тестами, красота!

    Вот только метод Is (чуть выше используется x => x.Author.Is(new BannedUserSpecification())) нужно трансформировать, чтобы получилось валидное выражение, понятное транслятору в SQL. При этом очень не хочется каждый предикат, использующий выше описанную функцию, пропускать через визитор. Это не то место, где нужна прозрачность, поэтому я и хочу расширить возможности EF для работы с этими функциями.
  • Как получить значение ParameterExpression?

    @iRumba Автор вопроса
    Так я их и так заранее собираю. Только функцию `MyFunction` надо трансформировать в другой вид :)

    Причем именно в другой вид, она не должна "как есть" транслироваться в SQL.
  • Как запретить VPN соединению пропихивать свой DNS?

    @iRumba Автор вопроса
    АртемЪ: спасибо, кэп.

    DHCP сервер находится далеко и ничего настроить я на нем не могу. Более того, DNS сервер там нужен, чтобы правильно обращаться к корпоративным ресурсам. Вот только он начинает использоваться для всех ресурсов.
  • Как запретить VPN соединению пропихивать свой DNS?

    @iRumba Автор вопроса
    Нет никаких клиентов. Стандартное виндовое VPN соединение
  • Как запретить VPN соединению пропихивать свой DNS?

    @iRumba Автор вопроса
    - Но роботы класса "Буратино" не могу нырять!
    - Не могут, но ныряют.

    До подключения VPN командой nslookup я вижу, что в качестве DNS у меня 192.168.1.1
    Этот адрес приходит с DHCP.

    После подключения VPN команда nslookup показывает другой DNS. В настройках VPN ДНС не указан (то есть тоже берется с DHCP).

    Короче, пропихивает, или нет, называйте как хотите, но после подключения VPN система начинает использовать другой DNS сервер
  • Как запретить VPN соединению пропихивать свой DNS?

    @iRumba Автор вопроса
    Вы хотели сказать шлюз? Если да, то нет :) шлюз не указан. Галочка снята
  • Как отлавливать перемещение одного окна над другим?

    @iRumba Автор вопроса
    Gorily: да не нужен мне этот контрол в моем проекте. Мне нужно "отловить перемещение одного окна над другим". Про табы гугл хрома я сказал лишь для примера.
  • Как отлавливать перемещение одного окна над другим?

    @iRumba Автор вопроса
    Gorily: Что? Да там не один десяток тысяч строк кода, из которых мне нужна, наверное, сотня или меньше и я понятия не имею как их найти. Я же конкретный вопрос задал, а получил ссылку на проект, в котором это где то как то реализовано.
  • Как отлавливать перемещение одного окна над другим?

    @iRumba Автор вопроса
    Спасибо, конечно, но я не могу там найти то, что мне нужно. Оно там, несомненно, есть, но зарыто в целой куче ненужных мне реализаций. (
    Это как если бы я спросил, как применить определенный фильтр к изображению, а мне бы дали ссылку на исходники фотошопа )))
  • Как сделать шаблон окна в WPF?

    @iRumba
    Артем Иванцов: что значит нельзя? Так вообще то и делают :)
  • Что написать на C#?

    @iRumba
    Виталий Пухов: я думаю, преподы знают про github )
    Думаю, на шарпе в эти 300 строк явно не входят фигурные скобочки )
    Это должны быть 300 строк чистого кода.
    Так что полагаю, что определение переменных, свойств, методов и тд тоже не учитывается.

    Да и вообще это шутка. Как раз ПО то я и сам напишу (нид айдиас), а вот с оформлением (ТЗ и тд) будут проблемы :)
  • Что написать на C#?

    @iRumba
    Виталий Пухов: Любую программу не менее 300 строк кода, к которой бы я мог прикрутить ТЗ и тестирование возможностей. )
  • Как в ItemsControl выполнить метод класса источника при возникновении события (например щелчка мышью)?

    @iRumba Автор вопроса
    Да да. Буквально перед прочтением сообщения пришел к этому же! )
    Сижу, разбираюсь с ICommand. учитывая, что использовать придется в нескольких местах, решил таки создать полноценную команду.
  • Как правильно написать шаблон для вставки HeaderedContentControl в TabControl?

    @iRumba Автор вопроса
    Если честно я с этого начал и уже не помню, почему я от этого ушел )
  • Как через DragDrop передать объект по ссылке?

    @iRumba Автор вопроса
    Дмитрий Макаров: а это уже ближе к правде. Как то не подумал о дополнительном процессе
  • Как через DragDrop передать объект по ссылке?

    @iRumba Автор вопроса
    Виталий Пухов: А если в нем при этом происходят фоновые процессы?
  • Как через DragDrop передать объект по ссылке?

    @iRumba Автор вопроса
    А что, если инициализация длится несколько секунд? А что, если эта инициализация еще и на БД давит? Повторная инициализация недопустима, проще просто отказаться от задумки, если нет иного решения.