如何从’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.HasValue/Value – 更长但相当的方法是:

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

观察HasValue一般适用于更改逻辑的语句,并注意如果maybeGuid是“没有值”,则Value将抛出exception – 为null – 这就是为什么需要保护的原因。

快乐的编码。


迂腐细节:等效方法不是“线程安全”。 也就是说,假设maybeGuid已共享,则可以在HasValueValue之间为其指定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 } }