如何从’Nullable ‘返回’Guid’?
我想在下面返回一个Guid值。 但是,数据库( 和我的dbml )将该列作为可以为nullable Guid
,它在.Select
部分生成一个exception,说它无法从IQueryable
转换为System.Guid
。
我猜我需要首先使我的返回值“ 具体 ”???? 真正?
如果是这样,我如何用Guid做到这一点?
public static Guid GetCurrentWorkerByType(int enrollmentID, int staffTypeID) { using (var context = CmoDataContext.Create()) { IQueryable tWorkHist = context.GetTable(); 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 // (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
– 更长但相当的方法是:
Guid theGuid = maybeGuid.HasValue ? maybeGuid.Value : Guid.Empty;
观察HasValue
一般适用于更改逻辑的语句,并注意如果maybeGuid是“没有值”,则Value
将抛出exception – 为null
– 这就是为什么需要保护的原因。
快乐的编码。
迂腐细节:等效方法不是“线程安全”。 也就是说,假设maybeGuid
已共享,则可以在HasValue
和Value
之间为其指定null
。 有许多SO问题涵盖了“线程安全” ??
(合并运算符) – 生成的IL有效地使用临时变量,因此该值可能是陈旧的,但不能抛出exception。
使用
.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类将结构包装在类中。
你得到的是一个没有为一个执行的查询,对于两个,它将返回一个Guids列表,据我所知。 如果你想要返回第一个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;
将FirstOrDefault与带有Guid.Empty的conjunticon一起使用
试试这个:
public static Guid GetCurrentWorkerByType(int enrollmentID, int staffTypeID) { using (var context = CmoDataContext.Create()) { IQueryable tWorkHist = context.GetTable (); 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 } }