开发者

How to return a 'Guid' from a 'Nullable<Guid>'?

I am trying to return a Guid value below. However the database(and my dbml) has that column as a nullable Guid and it is generating an exception on the .Select portion saying it can't convert from an IQueryable<System.Guid?> to a System.Guid.

I am guessing I need to make my return value "concrete" first???? True?

If so how do I do that with 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.E开发者_如何学PythonndDate > 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;

Also see Nullable<T>.HasValue/Value -- A longer, but equivalent, method would be:

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

Observe that HasValue may be suitable in general if statements to change logic and also note that Value will throw an exception if maybeGuid is "has no value" -- is null -- which is why the guard is required.

Happy coding.


Pedantic detail: The equivalent method is not "thread safe". That is, assuming maybeGuid was shared, it could be assigned null between HasValue and Value. There are a number of SO questions that cover the "thread safety" of ?? (the coalesce operator) -- the generated IL effectively uses a temporary variable so the value may be stale but an exception can't be thrown.


Use

.Select(workHist => workHist.Worker).Single();
  • .Select() returns a query that has not run.
  • If you use .Select().ToList() then you you return a list.
  • If you use .Select().Single() then you return one item and it makes sure only one item is there
  • If you use .Select().SingleOrDefault() then you return one item and default. Query must not contain more than 1 item.
  • If you use .Select().First() then you return the first item. Query must contain at least 1 item.
  • If you use .Select().FirstOrDefault() then you return the first item or default. Query can contain 1 or more or no items.


Try
Change your return type from System.Guid to ?System.Guid // nullable of guid Then add .FirstOrDefault() after the select call

A struct cannot be null, but the System.Nullable class wraps the struct in a class.


What you've got is a query that hasn't executed for one, and for two, it will return a list of Guids as far as I can tell. If you want to return the first Guid or default (which I believe is a zero'd out guid) you can say .FirstorDefault() after your select.


The closest you will get representing null with a Guid is to use Guid.Empty. So, for your query, you will probably want to first pick the value returned by FirstOrDefault, make a null check, and then return a reasnable value:

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;


Use FirstOrDefault with conjunticon with Guid.Empty

Try this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜