#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.