简体   繁体   中英

C# lambda null conditional

I have following DTO:

public class DTO_UserWithCreds
{
    public string Name { get; set; }

    public string Surname { get; set; }
    public string Ava1 { get; set; }
    public UserType Type { get; set; }
    public string Uid { get; set; }

    public DateTime? BanDateTime { get; set; }
    
    };

And I get users from database as following:

  var users = from vkuser in _context.VkUsers
                join contextUser in _context.Users on vkuser.Uid equals contextUser.Uid
                join userClaim in _context.UserClaims on contextUser.Id equals userClaim.UserId
                let userBanOffset = contextUser.LockoutEnd
                let userBan = userBanOffset.HasValue ? userBanOffset.Value.Date : null
                select new DTO_UserWithCreds
                { 
                    Name = vkuser.Name,
                    Surname = vkuser.Surname,
                    Ava1 = vkuser.Ava1,
                    Uid = vkuser.Uid,
                    Type =  DTO_UserWithCreds.FromString(userClaim.ClaimValue),
                    BanDateTime = userBan
                };
       

I get following error message (I dont really understand it to be honest): 错误描述

If I change request to this:

  var users = from vkuser in _context.VkUsers
                join contextUser in _context.Users on vkuser.Uid equals contextUser.Uid
                join userClaim in _context.UserClaims on contextUser.Id equals userClaim.UserId
                let userBanOffset = contextUser.LockoutEnd
               // let userBan = userBanOffset.HasValue ? userBanOffset.Value.Date : null
                select new DTO_UserWithCreds
                { 
                    Name = vkuser.Name,
                    Surname = vkuser.Surname,
                    Ava1 = vkuser.Ava1,
                    Uid = vkuser.Uid,
                    Type =  DTO_UserWithCreds.FromString(userClaim.ClaimValue),
                    BanDateTime = contextUser.LockoutEnd?.DateTime 
                };

I will have compile error that lambda inside expression tree cant contain null propagation operator. Is it possible to get this information like I want? Or I have to write second query?

You could cast the null to DateTime? :

let userBan = userBanOffset.HasValue ? userBanOffset.Value.Date : (DateTime?)null

You just missed a cast:

  var users = from vkuser in _context.VkUsers
                join contextUser in _context.Users on vkuser.Uid equals contextUser.Uid
                join userClaim in _context.UserClaims on contextUser.Id equals userClaim.UserId
                let userBanOffset = contextUser.LockoutEnd
                let userBan = userBanOffset.HasValue ? userBanOffset.Value.Date : (DateTime?)null
                select new DTO_UserWithCreds
                { 
                    Name = vkuser.Name,
                    Surname = vkuser.Surname,
                    Ava1 = vkuser.Ava1,
                    Uid = vkuser.Uid,
                    Type =  DTO_UserWithCreds.FromString(userClaim.ClaimValue),
                    BanDateTime = userBan
                };

Your problem is here:

let userBan = userBanOffset.HasValue ? userBanOffset.Value.Date : null

What type is userBan ? How is the compiler supposed to figure it out? userBanOffset.Value.Date is a DateTime , but null isn't and can't be a DateTime because DateTime is a value type and value types cannot be null.

So to solve this problem, you need to tell it that null is a Nullable<DateTime> so it can resolve the ambiguity:

let userBan = userBanOffset.HasValue ? userBanOffset.Value.Date : (DateTime?)null

You could also do:

let userBan = userBanOffset.HasValue ? (DateTime?)userBanOffset.Value.Date : null

But personally I always use the former. Depends on which you think is more readable.

Change

BanDateTime = contextUser.LockoutEnd?.DateTime

to

BanDateTime = (contextUser.LockoutEnd == null) ? null : contextUser.LockoutEnd.DateTime

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM