MongoDB C # Переопределение равенства не подобрано - PullRequest
0 голосов
/ 24 октября 2018

У меня есть следующие блоки кода:

    public bool Equals(TranslatedTextReference other)
    {
        if (other is null) return false;
        return Translations.Equals(other.Translations);
    }

    public bool Equals(string other)
    {
        foreach(KeyValuePair<string, string> pair in Translations)
        {
            if (other.Equals(pair.Value, StringComparison.InvariantCultureIgnoreCase))
                return true;
        }
        return false;
    }

    public static bool operator ==(TranslatedTextReference left, TranslatedTextReference right) => left.Equals(right);
    public static bool operator !=(TranslatedTextReference left, TranslatedTextReference right) => left.Equals(right);

    public static bool operator ==(TranslatedTextReference left, string right) => left.Equals(right);
    public static bool operator !=(TranslatedTextReference left, string right) => !left.Equals(right);

, который переопределяет поведение Equlas и == в пользовательском классе с именем TranslatedTextReference.И

database.GetCollection<Element>("elements").AsQueryable()
            .FirstOrDefault(element => element.TranslatedElementName == name);

, который теоретически должен запрашивать Mongo и использовать оператор overriden ==.На практике это не работает, поскольку (я предполагаю) переопределенный оператор фактически не вызывается, потому что запрос LINQ выполняется как запрос MongoDB непосредственно на сервере MongoDB.Фактически, этот другой фрагмент кода, который использует операторы равенства по умолчанию, работает отлично.

database.GetCollection<Element>("elements").AsQueryable()
            .FirstOrDefault(element => element.AtomicNumber == atomicNumber);

AtomicNumber - это целое число.

Есть ли способ заставить MongoDB использовать мой пользовательский оператор?

Кроме того, я знаю, что мог бы просто использовать операторы по умолчанию и создать тот же запрос с ними, но я должен использовать == или .Equals () в моем запросе LINQ.

1 Ответ

0 голосов
/ 24 октября 2018

Невозможно добиться такого поведения, потому что драйвер только «знает» определенные виды методов и может преобразовать их в запросы MongoDB.

Представьте, что вы написали все видыПрикольный код в вашей пользовательской реализации Equals (например, вызов веб-службы или регистрация чего-то другого или чего-то еще).Что бы сделал драйвер, чтобы перевести это в запрос MongoDB?

Когда вы посмотрите на код драйвера, вы увидите, что логика перевода просто основана на имени соответствующего метода в дереве выражений.что вы передаете в качестве предиката:

private FilterDefinition<BsonDocument> TranslateMethodCall(MethodCallExpression methodCallExpression)
{
    switch (methodCallExpression.Method.Name)
    {
        case "Contains": return TranslateContains(methodCallExpression);
        case "ContainsKey": return TranslateContainsKey(methodCallExpression);
        case "EndsWith": return TranslateStringQuery(methodCallExpression);
        case "Equals": return TranslateEquals(methodCallExpression);
        case "HasFlag": return TranslateHasFlag(methodCallExpression);
        case "In": return TranslateIn(methodCallExpression);
        case "IsMatch": return TranslateIsMatch(methodCallExpression);
        case "IsNullOrEmpty": return TranslateIsNullOrEmpty(methodCallExpression);
        case "StartsWith": return TranslateStringQuery(methodCallExpression);
    }

    return null;
}
...