[英]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?
您可以将
null
为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
? 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.Date
是DateTime
,但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.