LINQ 查询中使用的 C# 三元运算符
Posted
技术标签:
【中文标题】LINQ 查询中使用的 C# 三元运算符【英文标题】:C# Ternary Operator used in LINQ query 【发布时间】:2013-11-14 12:12:10 【问题描述】:是否可以使用三元运算符来体现这个逻辑?
if (a = 1)
somevalue = "hello";
else if (a = 2)
someValue = "world";
else if (a = 3)
someValue = "hellWorld";
我在 LINQ 查询中执行以下操作:
using (var data = new DAL())
var result = data.Holidays.AsNoTracking()
.Where(x => x.RequesterId == userId)
.Select(x => new HolidayModel
HolidayId = x.HolidayId,
FromDate = x.FromDate,
ToDate = x.ToDate,
AuthorisationStatus = x.InternalHolidayStatus == 1 ?
HolidayAuthStatus.Pending :
HolidayAuthStatus.Rejected,
DateModified = x.ModifiedDate
).ToList();
return Json(result.ToDataSourceResult(request));
HolidayAuthStatus
是一个枚举,其中包含三个值(Pending
(1)、Authorised
(2) 和 Rejected
(3));我想在分配AuthorisationStatus
的值时在代码中反映这一点。
【问题讨论】:
显然你已经在使用它了,有什么问题吗?此外,如果HolidayAuthStatus
对应于AuthorisationStatus
,您可以直接进行转换。
这是 LINQ-to-Objects、LINQ-to-SQL 还是 LINQ-to-Entities?
【参考方案1】:
改成这个
AuthorisationStatus = (HolidayAuthStatus)x.InternalHolidayStatus
如果您的 HolidayAuthStatus 的整数值与 InternalHolidayStatus 值匹配,它将起作用。这里的三元运算符看起来很糟糕。如果您的状态码不匹配,最好让函数接受int status
并返回HolidayAuthStatus
HolidayAuthStatus GetStatus(int status)
if(status == 1) return HolidayAuthStatus.Pending;
if(status == 2) return HolidayAuthStatus.Authorised;
if(status == 3) return HolidayAuthStatus.Rejected;
return HolidayAuthStatus.Unknown; // for e.g.
并像这样使用它:
AuthorisationStatus = GetStatus(x.InternalHolidayStatus)
编辑:
正如@James 所说,该方法仅适用于 Linq-to-object 而不是 Linq-to-entities
【讨论】:
方法方法很可能只适用于 LINQ To Objects。 @James 好点我还没有看到DAL()
在使用中,我会写在我的回答中,谢谢
@wudzik 谢谢,这是一种巧妙的方法,但它在 LINQ 查询中不起作用。返回此错误:LINQ to Entities 无法识别方法 'Timeshet.Web.Models.Enum.HolidayAuthStatus GetStatus(Int32)' 方法,并且此方法无法转换为商店表达式
@t_plusplus 是的,我现在知道了,因为它是 linq-to-entities 我错过了这一点,James 指出了这一点。第一种方法适用于 linq-to-entites,仅次于 linq-to-objects。使用(HolidayAuthStatus)x.InternalHolidayStatus
检查第一个答案
@t_plusplus 您仍然可以使方法工作,但是,您需要实现查询并然后进行投影,即data.Holidays.AsNoTracking().Where(...).AsEnumerable().Select(...).ToList();
【参考方案2】:
是的,这是可能的。我认为很难用三元运算符获得运算符优先级,所以我更喜欢使用括号:
AuthorizationStatus = x.InternalHolidayStatus == 1 ?
HolidayStatus.Pending :
(x.InternalHolidayStatus == 2 ?
HolidayStatus.Rejected :
(x.InternalHolidayStatus == 3 ?
HolidayStatus.Authorized :
HolidayStatus.Invalid))
由于这是到枚举的映射,因此也可以按照@wodzik 的建议使用强制转换,前提是可以且可行地为枚举值使用与数据库中相同的值。
要使用它,您必须明确地为枚举赋值
public enum HolidayStatus
Pending = 1,
Rejected = 2,
Authorized = 3
那么你可以这样做:
AuthorizeStatus = (HolidayStatus)x.InternalHolidayStatus
【讨论】:
您有更好的格式化建议吗?不幸的是,C# 中没有 switch-case 运算符,只有不能在 LINQ 查询中使用的语句。 我不会嵌套三元运算符。 @RichardEv 嵌套三元运算符有什么问题?您失去了一些可读性,但它仍然功能上正确。 问题是专门询问是否可以使用三元运算符,这就是我的答案。我知道代码很难看,但对于 Linq-to-Entities,不可能将表达式分解为单独的方法。 对我(以及我最近合作过的团队)来说,一切都与可读性有关。但是你是对的,三元是我们所要求的......而且我知道使用 Linq-to-Entities 时存在限制。以上是关于LINQ 查询中使用的 C# 三元运算符的主要内容,如果未能解决你的问题,请参考以下文章