Как вернуть 'Guid' из 'Nullable <Guid>'? - PullRequest
1 голос
/ 14 апреля 2011

Я пытаюсь вернуть значение Guid ниже. Однако база данных ( и мой dbml ) имеет этот столбец как nullable Guid, и она генерирует исключение для части .Select, говоря, что она не может преобразовать из IQueryable<System.Guid?> в System.Guid ,

Я предполагаю, что мне нужно сначала сделать возвращаемое значение " конкретное " ???? Правда?
Если так, то как мне это сделать с Guid?

public static Guid GetCurrentWorkerByType(int enrollmentID, int staffTypeID)
{
    using (var context = CmoDataContext.Create())
    {
        IQueryable<tblWorkerHistory> tWorkHist = context.GetTable<tblWorkerHistory>();

        return (tWorkHist.Where(workHist => 
            (workHist.EnrollmentID == enrollmentID) &&
            (workHist.tblStaff.StaffTypeID == staffTypeID) &&
            (workHist.EndDate == null || workHist.EndDate > DateTime.Now))
            .Select(workHist => workHist.Worker));
        }
    }
}

Ответы [ 6 ]

12 голосов
/ 14 апреля 2011
// Get the Guid? itself, for sake of example from IQueryable<Guid?>
// (could be `null` from DB value or because queryable was empty)
Guid? maybeGuid = queryable.FirstOrDefault();
// Need to have *a* GUID or default it to something
// because a Guid is a value-type and needs *a* value.
Guid theGuid = maybeGuid ?? Guid.Empty;

Также см. Nullable<T>.HasValue/Value - более длинный, но эквивалентный метод будет:

Guid theGuid = maybeGuid.HasValue ? maybeGuid.Value : Guid.Empty;     

Обратите внимание, что HasValue может подойти в общем случае if для изменения логикиТакже обратите внимание, что Value сгенерирует исключение, если MaybeGuid "не имеет значения" - null - поэтому требуется защита.

Счастливое кодирование.


Педантичная деталь: эквивалентный метод не является "безопасным для потоков".То есть, предполагая, что maybeGuid является общим, ему может быть назначено null между HasValue и Value.Существует ряд вопросов SO, которые охватывают «безопасность потока» ?? (оператор объединения) - сгенерированный IL эффективно использует временную переменную, поэтому значение может быть устаревшим, но исключение не может быть выдано.

2 голосов
/ 14 апреля 2011

Попробуйте
Измените тип возврата с System.Guid на? System.Guid // обнуляемый из guid Затем добавьте .FirstOrDefault () после вызова select

Структура не может быть нулевой, но класс System.Nullable оборачивает структуру в класс.

2 голосов
/ 14 апреля 2011

Используйте

.Select(workHist => workHist.Worker).Single();
  • .Select() возвращает запрос, который еще не был выполнен.
  • Если вы используете .Select().ToList(), то вы возвращаете список.
  • Если вы используете .Select().Single(), то вы возвращаете один элемент, а гарантирует, что там только один элемент
  • Если вы используете .Select().SingleOrDefault(), вы возвращаете один элемент и значение по умолчанию. Запрос не должен содержать более 1 элемента.
  • Если вы используете .Select().First(), вы возвращаете первый товар. Запрос должен содержать хотя бы 1 элемент.
  • Если вы используете .Select().FirstOrDefault(), то вы возвращаете первый элемент или значение по умолчанию. Запрос может содержать 1 или более элементов или не содержать их.
2 голосов
/ 14 апреля 2011

То, что у вас есть, - это запрос, который не был выполнен для одного, а для двух, насколько я могу судить, он вернет список Guids. Если вы хотите вернуть первый Guid или значение по умолчанию (которое я считаю guid с нулевым значением), вы можете сказать .FirstorDefault () после вашего выбора.

1 голос
/ 14 апреля 2011

Используйте FirstOrDefault вместе с Guid.Empty

Попробуйте:

public static Guid GetCurrentWorkerByType(int enrollmentID, int staffTypeID)
{
 using (var context = CmoDataContext.Create())
 {
  IQueryable<tblWorkerHistory> tWorkHist = context.GetTable<tblWorkerHistory>();
    var guid = (tWorkHist.Where(workHist => (workHist.EnrollmentID == enrollmentID) && 
                    (workHist.tblStaff.StaffTypeID == staffTypeID) &&(workHist.EndDate == null || workHist.EndDate > DateTime.Now))
        .Select(workHist => workHist.Worker)
     ///####NOTICE THE USE OF FirstOrDefault
        ).FirstOrDefault();
    return (guid.HasValue)?guid.Value:Guid.Empty
    }
}
1 голос
/ 14 апреля 2011

Самое близкое, которое вы получите, представляющее null с Guid, - это Guid.Empty.Таким образом, для вашего запроса вы, вероятно, захотите сначала выбрать значение, возвращаемое FirstOrDefault, выполнить нулевую проверку, а затем вернуть повторно определяемое значение:

Guid? result = tWorkHist.Where(workHist => 
                   (workHist.EnrollmentID == enrollmentID) 
                   && (workHist.tblStaff.StaffTypeID == staffTypeID) 
                   && (workHist.EndDate == null || workHist.EndDate > DateTime.Now))
                   .Select(workHist => workHist.Worker)
                   .FirstOrDefault();

return result.HasValue ? result.Value : Guid.Empty;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...