如何从'Nullable <guid>'返回'Guid'?</guid>

时间:2011-04-14 19:35:35

标签: c# .net linq linq-to-sql

我正在尝试在下面返回 Guid 值。但是,数据库(和我的dbml )将该列作为nullable Guid,并且它在.Select部分生成异常,表示无法从{{1}转换到IQueryable<System.Guid?>

我猜我需要首先让我的返回值“ 具体 ”?真的吗?
如果是这样,我如何用Guid做到这一点?

System.Guid

6 个答案:

答案 0 :(得分:12)

// 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为“没有值”则会抛出异常 - 是{{ 1}} - 这就是需要守卫的原因。

快乐的编码。


迂腐细节:等效方法不是“线程安全”。也就是说,假设共享null,可以在maybeGuidnull之间分配HasValue。有许多SO问题涵盖Value(合并运算符)的“线程安全性” - 生成的IL有效地使用临时变量,因此值可能是陈旧的但不能抛出异常。

答案 1 :(得分:2)

你得到的是一个没有为一个执行的查询,对于两个,它将返回一个Guids列表,据我所知。如果你想要返回第一个Guid或默认值(我认为是一个归零的guid),你可以在选择后说.FirstorDefault()。

答案 2 :(得分:2)

使用

.Select(workHist => workHist.Worker).Single();
  • .Select()返回尚未运行的查询。
  • 如果您使用.Select().ToList(),则返回一个列表。
  • 如果您使用.Select().Single(),那么您会返回一个项目确保只有一个项目
  • 如果您使用.Select().SingleOrDefault(),则返回一项默认值。查询不得包含多于1个项目。
  • 如果您使用.Select().First(),则返回第一项。查询必须包含至少1个项目。
  • 如果您使用.Select().FirstOrDefault(),则返回第一项或默认值。查询可以包含1个或多个项目。

答案 3 :(得分:2)

尝试
    将您的返回类型从System.Guid更改为?System.Guid //可为空的guid     然后在select调用

之后添加.FirstOrDefault()

结构不能为null,但System.Nullable类将结构包装在类中。

答案 4 :(得分:1)

使用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;

答案 5 :(得分:1)

将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
    }
}