Задать вопрос
Actor
@Actor

Какой должен быть результат поиска если данных нет?

Возьмем класическую схему, база и приложение.
В приложении есть класс для работы с базой, есть метод поиска по определнному полю, который должен возвращать данные в некой структуре
class SomeRecord
{
  public string prop1 {get;set;}
  public string prop1 {get;set;}
}

И есть метод котоырй ищет по полю:
...
public SomeRecord FindMe(string prop)
{
  var l = <linq query>
  return l.First<SomeRecord>(); 
}

Если LINQ запрос не выдаст результата (т.е. Count = 0) то return выпадет с ошибкой. Как правильно поступать в таких случаях?
  • Вопрос задан
  • 2269 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
aush
@aush
Правильно - возвращать коллекцию результатов поиска. Если результатов нет, то будет возвращаться пустая коллекция.

Если же у вас контракт такой, что "должен возвращаться только один результат", то FindMe должен выбрасывать исключение, т.к. он не смог выполнить контракт "вернуть один результат" (null - это не результат).

Null можно вовзвращать только если вы на самом деле хотите использоваться такой контракт: "возвращать один результат или null". Но подобный дизайн не приводит ни к чему хорошему и только увеличивает сложность.
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
GavriKos
@GavriKos
return null. Тем более раз вы класс используете.
Ответ написан
Комментировать
return l.FirstOrDefault<SomeRecord>();

и ожидать возможного null в результате. Либо обрабатывать ответ до возврата
public SomeRecord FindMe(string prop)
{
  var l = <linq query>
  SomeRecord result = l.FirstOrDefault<SomeRecord>(); 
  if(result == null) {
    result = new SomeRecord();
  }
  return result;
}

Но в таком случае, при дефолтной инициализации SomeRecord, надо устанавливать какой то флаг в экземпляре, который бы указывал на то что это пустое значение SomeRecord.
Ответ написан
Комментировать
var result = l.SingleOrDefault();

1. Вот еще вариант для дальнейшей обработки: использовать что то типа Option из F# (или Nullable в C#)
Так, что б был сразу понятен контракт метода

public class SingleResult<T> where T : class { 
  private readonly T result;
  public readonly bool IsSuccess;

  private SingleResult(T result, bool isSuccess) {
    this.result = result;
     IsSuccess = isSuccess;
  }

  public T Result { 
    get {
       Contract.Requires<InvalidOperationException>(IsSuccess);
       return result;
     }
   }

   public static SingleResult<T> Success(T result) {
     Contract.Requires<ArgumentNullException>(result != null, "result");
     
     return new SingleResult<T>(result, true);
   }

   public static SingleResult<T> Nothing = new SingleResult<T>(null, false);
}


public SingleResult<SomeRecord> FindMe(string prop)         {
  var l = <linqquery >;
  
  var result = l.SingleOrDefault();
  if (result == null)
    return SingleResult<SomeRecord>.Nothing;
        
  return SingleResult<SomeRecord>.Success(result); 
}


2. Можно по типу TryParse
public bool TryFindSingle(string prop, out SomeRecord result) {...}
Ответ написан
Комментировать
Neuroware
@Neuroware
Программист в свободное от работы время
Инкапсуляция вселенной!
dnews-files-2014-10-binterstellar-black-
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы