Вы также можете использовать агрегат:
db.accommodations.aggregate(
[
{$project: {_id:1, name:1, zipcode:1,
size_of_name: {$size: "$name"}
}
},
{$match: {"size_of_name": {$gt: 1}}}
])
// вы добавляете «size_of_name» для переноса документа и используете его для фильтрации размера имени
Я вижу базовую проблему теперь. Это глубже, чем я сначала думал. В основном решение состоит в том, чтобы изменить дерево выражений прежде, чем сериализировать его путем замены всех поддеревьев, которые не зависят от параметров с постоянными узлами. Это, по-видимому, называют "funcletization". Существует объяснение его здесь.
Просто сделайте другое закрытие...
Скажите, что-то как:
var prepend = "OLD:";
Func<string, Func<string, string>> makePrepender = x => y => (x + y);
Func<string, string> oldPrepend = makePrepender(prepend);
prepend = "NEW:";
Console.WriteLine(oldPrepend("Brownie"));
Havn't протестировал его все же, поскольку у меня нет доступа к VS в данный момент, но обычно, это - то, как я решаю такую проблему.
Я получаю проблему теперь: лямбда относится к содержанию класса, который не мог бы быть сериализуемым. Затем сделайте что-то вроде этого:
public void static Func<string, string> MakePrependAction(String prefix){
return (x => prefix + x);
}
(Отметьте статическое ключевое слово.) Затем лямбда не должна ссылаться на содержание класса.
Лямбды автоматически 'сосут' в локальных переменных, я боюсь, что это просто, как они работают по определению.
Это - довольно типичная проблема т.е. переменные, изменяемые закрытием неумышленно - далекое простое решение состоит в том, чтобы только пойти:
string prefix = "OLD:";
var actionPrefix = prefix;
Func<string, string> prependAction = (x => actionPrefix + x);
prefix = "NEW:";
Console.WriteLine(prependAction("brownie"));
При использовании resharper, он на самом деле определит места в коде, где Вы подвергаетесь риску вызывать неожиданные побочные эффекты, такие как это - поэтому, если файл является "полностью зеленым" Ваш код, должен быть в порядке.
Я думаю до некоторой степени, что было бы хорошо, если у нас было немного синтаксического сахара для обработки этой ситуации, таким образом, мы, возможно, записали это как остроту т.е.
Func<string, string> prependAction = (x => ~prefix + x);
Где некоторый префиксный оператор заставил бы значение переменной быть оцененным до построения анонимного делегата/функции.
Уже существует несколько ответов, здесь объясняя, как можно избежать лямбды, "снимающей" переменную. К сожалению, это не решает Вашу базовую проблему. Неспособность сериализировать лямбду не имеет никакого отношения к лямбде, "снимавшей" Вашу переменную. Если для лямбда-выражения нужен экземпляр несериализировать класса для вычислений, оно имеет смысл, что оно не может быть сериализировано.
В зависимости от того, что Вы на самом деле пытаетесь сделать (я не могу вполне решить из Вашего сообщения), решение состояло бы в том, чтобы переместить несериализуемую часть лямбды снаружи.
Например, вместо:
NonSerializable nonSerializable = new NonSerializable();
Func<string, string> prependAction = (x => nonSerializable.ToString() + x);
использование:
NonSerializable nonSerializable = new NonSerializable();
string prefix = nonSerializable.ToString();
Func<string, string> prependAction = (x => prefix + x);
Что относительно этого
string prefix = "OLD:";
string _prefix=prefix;
Func<string, string> prependAction = (x => _prefix + x);
prefix = "NEW:";
Console.WriteLine(prependAction("brownie"));
Как насчет:
string prefix = "OLD:";
string prefixCopy = prefix;
Func<string, string> prependAction = (x => prefixCopy + x);
prefix = "NEW:";
Console.WriteLine(prependAction("brownie"));
?
Ну, если мы собираемся говорить о "проблемах" здесь, лямбды прибывают из мира функционального программирования, и на языке чисто функционального программирования, нет никаких присвоений и таким образом, Ваша проблема никогда не возникала бы, потому что значение префикса никогда не могло изменяться. Я понимаю, что C# думает, что здорово импортировать идеи из функциональных программ (потому что FP прохладен!), но очень трудно сделать это симпатичным, потому что C# и всегда будет императивным языком программирования.