繁体   English   中英

在EF6 / LINQ中集中三元逻辑

[英]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.

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