简体   繁体   English

C# lambda null 有条件

[英]C# lambda null conditional

I have following DTO:我有以下 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.我将有编译错误,即表达式树内的 lambda 不能包含 null 传播运算符。 Is it possible to get this information like I want?是否可以像我想要的那样获得这些信息? Or I have to write second query?或者我必须写第二个查询?

You could cast the null to DateTime?您可以将nullDateTime? :

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 ? 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. userBanOffset.Value.DateDateTime ,但null不是也不能是DateTime ,因为DateTime是值类型,值类型不能是 null。

So to solve this problem, you need to tell it that null is a Nullable<DateTime> so it can resolve the ambiguity:所以要解决这个问题,你需要告诉null是一个Nullable<DateTime>所以它可以解决歧义:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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