[英]Centralize ternary logic in EF6/LINQ
我似乎經常(在處理枚舉時)執行以下操作:
.Select(x => new {
enumDesc = (
x.status == GoodStatus ? "Good!"
: x.status == BadStatus ? "Bad<angryface>"
: x.status == Unknown ? "no clue"
)
})
要么
let enumDesc = (
x.status == GoodStatus ? "Good!"
: x.status == BadStatus ? "Bad<angryface>"
: x.status == Unknown ? "no clue"
)
有些查詢最終會遇到許多這樣的情況,例如我現在正在處理的項目。 這樣做很不錯,因為它可以轉換為SQL case語句,因此比在實現之后進行迭代要快。 但是,在我當前的項目中,我需要在多個位置/查詢中執行此操作。 有什么方法可以執行且可重用(即轉換為SQL)而不重構結構(例如,將枚舉移動到表中)嗎? 我還沒辦法提出。 如果我可以僅捕獲或別名三元數據,那就足夠了,或者創建一個從常量或屬性或其他東西中“選擇”的表達式...
如果您願意避免使用if
邏輯,請考慮以下事項:
我經常看到C#中的開發人員傾向於使用DescriptionAttribute
並將其與擴展方法結合起來以查找enum
值的描述值。
public enum Status
{
[Description("no clue")]
Unknown,
[Description("Good!")]
Good,
[Description("Bad<angryface>")]
Bad
}
public static class EnumExt
{
public static string Description<T>(this T source)where T : struct, IConvertible
{
if (!typeof (T).IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}
var fi = source.GetType().GetField(source.ToString());
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : source.ToString();
}
}
這是一個有效的.NET小提琴,我迅速地進行了演示。
否則,如果要在不使用屬性的情況下將字符串映射到enum
值,則建議switch
...
您可以使用實現Expression<Func<T, T2>>
,請參見下面的示例:
public enum Status
{
GoodStatus,
BadStatus,
Unknown
}
public class foo
{
public Status status;
}
public void Execute()
{
List<foo> list = new List<foo>
{
new foo
{
status = Status.BadStatus
},
new foo
{
status = Status.GoodStatus
},
new foo
{
status = Status.GoodStatus
},
new foo
{
status = Status.Unknown
}
};
var descStatus = list.Select(GetStatus).ToList();
}
public Expression<Func<foo, object>> GetStatus(foo _foo)
{
return x => new
{
enumDesc = _foo.status == Status.GoodStatus
? "Good!"
: _foo.status == Status.BadStatus
? "Bad<angryface>"
: _foo.status == Status.Unknown ? "no clue" : ""
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.