如何从“ Nullable <Guid>”返回“ Guid”?

问题描述

| 我正在尝试在下面返回Guid值。但是,数据库(和我的dbml)将该列作为
nullable Guid
,并且正在
.Select
部分生成一个异常,表示它无法从ѭ2转换为
System.Guid
。 我猜我需要先使返回值“具体”吗????真正? 如果是这样,我该如何使用Guid's?
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));
        }
    }
}
    

解决方法

// 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
语句中可能适用于更改逻辑,并且还请注意,如果也许Guid为“没有值”(is11),则
Value
会引发异常。这就是为什么需要保护的原因。 快乐的编码。 详细信息:等效方法不是“线程安全”。即,假设共享了“ 12”,则可以在“ 8”和“ 10”之间分配“ 11”。有许多SO问题涵盖了
??
(合并运算符)的“线程安全性”-生成的IL有效地使用了一个临时变量,因此该值可能是陈旧的,但不会引发异常。     ,采用
.Select(workHist => workHist.Worker).Single();
.Select()
返回未运行的查询。 如果使用
.Select().ToList()
,则返回列表。 如果您使用
.Select().Single()
,则返回一项,并确保其中只有一项 如果使用
.Select().SingleOrDefault()
,则返回一个项目和默认值。查询不得包含超过1个项目。 如果使用
.Select().First()
,则返回第一项。查询必须至少包含1个项目。 如果使用
.Select().FirstOrDefault()
,则返回第一项或默认值。查询可以包含1个或多个或没有任何项目。     ,尝试     将您的返回类型从System.Guid更改为?System.Guid //可为空的guid     然后在select调用之后添加.FirstOrDefault() 结构不能为null,但是System.Nullable类将结构包装在一个类中。     ,您所得到的是对一个查询没有执行的查询,对于两个查询,就我所知,它将返回一个Guid列表。如果要返回第一个Guid或默认值(我相信它是零的guid),则可以在选择后说.FirstorDefault()。     ,用
Guid
表示
null
时,最接近的是使用
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;
    ,在带有Guid.Empty的conjunticon中使用FirstOrDefault 尝试这个:
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
    }
}