запрос ravendb linq не использует переопределенный метод equals?

#c# #linq #ravendb #hashcode #equality

#c# #linq #ravendb #хэш-код #равенство

Вопрос:

Это работает :

 IQueryable<Record> query = _db.Query<Record>()
                .Statistics(out stats)
                .Where(r => r.Keywords.Any(
                 k => k.Value.Equals(searchInputModel.Keyword.Value)));
 

но это не

  IQueryable<Record> queryBorked = _db.Query<Record>()
                .Statistics(out stats)
                .Where(r => r.Keywords.Any(
                k => k.Equals(searchInputModel.Keyword)));
 

несмотря на то, что я переопределил equals и hashcode для ключевого слова class, как показано ниже, поэтому проверяется только значение на равенство :

 protected bool Equals(Keyword other)
        {
            return string.Equals(Value, other.Value, StringComparison.InvariantCultureIgnoreCase);

        }

        public override bool Equals(object obj)
        {

            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((Keyword) obj);
        }
 

И хэш-код :

 public override int GetHashCode()
        {
            unchecked
            {
                return (Value.ToLower().GetHashCode() * 397);
                //return (Value.ToLower().GetHashCode()*397) ^ Vocab.ToLower().GetHashCode();
            }
        }
 

Использует ли ravendb другую проверку на равенство?

Ответ №1:

RavenDB использует свою собственную реализацию, подобную Linq, на стороне базы данных (запрос возвращает IRavenQueryable вместо «обычного» запрашиваемого объекта .NET), поэтому невозможно использовать переопределенную реализацию как таковую в вашем запросе.

Будет работать следующее:

 IQueryable<Record> queryBorked = _db.Query<Record>()
            .Statistics(out stats)
            .ToList()
            .Where(r => r.Keywords.Any(
            k => k.Equals(searchInputModel.Keyword)));
 

Обратите внимание на «ToList()». Это вернет результаты всех записей, которые затем вы можете дополнительно уменьшить, используя реализацию .NET Linq и, следовательно, также вашу переопределенную реализацию Equals .

Однако обратите внимание, что это вернет все данные записи из базы данных и что ВЫ дополнительно сокращаете данные в коде, используя where-предложение. В то время как ваш первый, рабочий пример выполнит предложение where в базе данных и вернет вам только сокращенный набор результатов записи.

Комментарии:

1. это где-нибудь задокументировано?

2. Не как таковой, но здесь: link В нем упоминается ограниченная поддержка Linq.

3. Любой IQueryable зависит от превращения вашего дерева выражений в запрос, который отправляется поставщику этого запроса. Это имеет фундаментальное значение для использования LINQ-to- (что-то удаленное) вместо LINQ-to-Objects и не имеет ничего общего конкретно с RavenDB. Вы бы увидели то же самое с Entity Framework или с запросом OData.