问题描述
|
我正在尝试在下面返回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
}
}