c# - 枚举作为类属性

标签 c# .net linq-to-sql .net-4.0 enums

我有一个简单的类,Status,它包含两个属性。我想对其中一个属性(StatusID)使用枚举,这样我就可以消除一堆魔术字符串。

我的问题是如何使用它,例如:我有一个方法,它返回一个用于在下拉框中进行绑定(bind)的列表,如下所示 -->

public static IList<Status> GetAdminStatuses()
{
  IQueryable<Status> stat=context.tblAdminStatus
       .Where(s => s.InactiveDate > DateTime.Now || s.InactiveDate == null)
       .Select(s => new Status()
       {
         StatusID=s.StatusID,
         StatusDescription=s.StatusDesc
       });
   return stat.ToList();
}

它显然不喜欢我的 StatusID=s.StatusID 部分,因为数据库将其存储为 varchar。我是否在这里遗漏了一些简单的东西,或者我是否陷入了菜鸟领域并且不应该这样做?

这里是类和枚举供引用:

public class Status
{
  public string StatusID {get; set;}
  public string StatusDescription {get; set;}
}

public enum MyStatusID
{
  draft, pending, declined, accepted, close 
}

编辑

因此,按照这里的建议,我能够编译我的方法,但是在运行时我得到以下信息 --> Method 'System.Object Parse(System.Type, System.String)' has no support conversion到 SQL。

想法?


编辑 - 根据请求完整的方法,谢谢(注意 NoaStatusID == MyStatusID)

   public static IList<Status> GetAdminStatuses(NoaStatusID currentStatus = NoaStatusID.draft)
    {
        using (var context = MemberDataContext.Create())
        {
            IQueryable<Status> stat=context.tblAdminStatus
                   .Where(s => s.InactiveDate > DateTime.Now || s.InactiveDate == null)
                   .Select(s => new Status()
                     {
                       StatusID=NoaStatusID)Enum.Parse(typeof(NoaStatusID),s.StatusID),
                       StatusDescription=s.StatusDesc
                     });

            switch (currentStatus)
            {
                case NoaStatusID.draft:
                    stat=stat.Where(s => (s.StatusID == NoaStatusID.draft || s.StatusID == NoaStatusID.pending));                                                     
                    break;
                case NoaStatusID.pending:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.accepted || s.StatusID ==NoaStatusID.declined || s.StatusID ==NoaStatusID.pending));
                    break;                        
                case NoaStatusID.declined:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.draft || s.StatusID == NoaStatusID.pending || s.StatusID == NoaStatusID.declined));
                    break;
                case NoaStatusID.accepted:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.mailed || s.StatusID == NoaStatusID.monitor || s.StatusID == NoaStatusID.close || s.StatusID == NoaStatusID.accepted));
                    break;
                case NoaStatusID.mailed:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.mailed || s.StatusID == NoaStatusID.monitor || s.StatusID == NoaStatusID.close || s.StatusID == NoaStatusID.appeal));
                    break;
                case NoaStatusID.monitor:
                case NoaStatusID.appeal:
                case NoaStatusID.close:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.close || s.StatusID == NoaStatusID.appeal));   
                    break;                    
            }


            return stat.ToList();
        }
    }

最佳答案

我相信您正在寻找的是:

StatusID = (MyStatusID)Enum.Parse(typeof(MyStatusID), s.StatusID),

在 .Net 4.0 中还有一个 Enum.TryParse(string, out enum) 但在 .Select() 中并不是那么有用

或者: 尽管在大多数情况下效率较低,但您可以将 Status.StatusID 保留为字符串,并添加一个只读属性 StatusEnum 来动态输出 Enum 值:

public MyStatusID StatusEnum {
    get {
        return (MyStatusID)Enum.Parse(typeof(MyStatusID), StatusID)
    }

    private set;
}

in .Net 4.0:
public MyStatusID StatusEnum {
    get {
        MyStatusID value;
        if(!Enum.TryParse(StatusID, out value)
          value = MyStatusID.Default; // default value, instead of Exception throwing

        return value;
    }

    private set;
}

此替代方案每次读取实例时都会重新解析值。StatusEnum 被读取,因此我不推荐它,除非 LINQ 讨厌第一种方法


回复您上次的编辑:

在您的示例中,Enum.Parse() 可以很好地转换为 SQL。问题出在 switch 语句中,您在其中添加了与 Enum 进行比较的 .Where() 子句。 LINQ 不知道如何将 Enum == Enum 转换为 SQL,但它确实知道如何使用 C# 对象执行此操作。所以最简单的解决方案是 ToList() 它们并在本地进行比较。不幸的是,这意味着它从数据库下载所有状态类型的行,然后在本地过滤它们。如果您有数百万条记录,这可能不合理:

   public static IList<Status> GetAdminStatuses(NoaStatusID currentStatus = NoaStatusID.draft)
    {
        using (var context = MemberDataContext.Create())
        {
            List<Status> stat=context.tblAdminStatus
                   .Where(s => s.InactiveDate > DateTime.Now || s.InactiveDate == null)
                   .Select(s => new Status()
                     {
                       StatusID=NoaStatusID)Enum.Parse(typeof(NoaStatusID),s.StatusID),
                       StatusDescription=s.StatusDesc
                     })
                   .ToList();

            switch (currentStatus)
            {
                case NoaStatusID.draft:
                    stat=stat.Where(s => (s.StatusID == NoaStatusID.draft || s.StatusID == NoaStatusID.pending)).ToList();                                                     
                    break;
                case NoaStatusID.pending:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.accepted || s.StatusID ==NoaStatusID.declined || s.StatusID ==NoaStatusID.pending)).ToList();
                    break;                        
                case NoaStatusID.declined:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.draft || s.StatusID == NoaStatusID.pending || s.StatusID == NoaStatusID.declined)).ToList();
                    break;
                case NoaStatusID.accepted:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.mailed || s.StatusID == NoaStatusID.monitor || s.StatusID == NoaStatusID.close || s.StatusID == NoaStatusID.accepted)).ToList();
                    break;
                case NoaStatusID.mailed:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.mailed || s.StatusID == NoaStatusID.monitor || s.StatusID == NoaStatusID.close || s.StatusID == NoaStatusID.appeal)).ToList();
                    break;
                case NoaStatusID.monitor:
                case NoaStatusID.appeal:
                case NoaStatusID.close:
                    stat = stat.Where(s => (s.StatusID == NoaStatusID.close || s.StatusID == NoaStatusID.appeal)).ToList();   
                    break;                    
            }


            return stat;
        }
    }

关于c# - 枚举作为类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11440410/

相关文章:

linq-to-sql - LINQ 关系(亟待解决的问题)

c# - 我应该如何处理 XmlSerializer 创建的资源?

c# - 在 C# 优化中使用 Replace 和 Substring 过滤字符串

.net - LINQ查询帮助: searching for data in a Many to Many using Entity Framework

c# - 加速 linq 实体查询

c# - 使用 .NET OpenSSL 包装器签署文件

c# - 在 LINQ to SQL 中动态构造 "or"LIKE 查询

c# - 如何使用 LINQ to SQL 和 DbLinq 选择空值?

c# - 操作无法完成。无效指针 - VS2010 SP1

c# - 如何检测 C# 类中的方法是否实现了接口(interface)中的方法?