作为类属性的枚举

时间:2012-07-11 19:54:28

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

我有一个简单的类,Status,它包含两个属性。我想为其中一个属性(StatusID)使用Enum,这样我就可以消除一堆Magic Strings。

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

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。我在这里错过了一些简单的东西,或者我偶然发现了noob领域,不应该这样做吗?

这里的参考是Class和Enum:

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

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

修改

所以接受这里的建议我能够得到我的方法来编译,但是在运行时我得到以下内容 - &gt; Method 'System.Object Parse(System.Type, System.String)' has no supported translation to 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();
        }
    }

4 个答案:

答案 0 :(得分:1)

你找不到what

 Colors colorValue = (Colors) Enum.Parse(typeof(Colors), colorString);

答案 1 :(得分:1)

我相信你所寻找的是:

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语句中,您要添加与.Where()进行比较的Enum子句。 LINQ不知道如何将Enum == Enum转换为SQL,但确实知道如何使用C#对象。所以最简单的解决方案是ToList()它们并在本地进行比较。不幸的是,这意味着它从数据库中下载-all- Status类型的行,然后在本地过滤它们。如果您有数百万条记录,这可能不合理:

   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;
        }
    }

答案 2 :(得分:0)

如果您将支持字段*设为int,它就可以正常工作。

实际上,您甚至可以使用byte枚举(smallint支持字段)。

然而,设计师存在问题。 IIRC,enum声明需要在同一名称空间中。

注意:通过支持字段,我的意思是数据库表列类型。

答案 3 :(得分:0)

我的猜测是你想要String等效的枚举值,但不是很清楚:

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

编辑:鉴于评论,听起来像你想要的那样:

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

编辑:鉴于(进一步)评论,听起来像你想要的那样:

public static IList<Status> GetAdminStatuses()
{
  IQueryable<Status> stat=context.tblAdminStatus
       .Where(s => s.InactiveDate > DateTime.Now || s.InactiveDate == null)
       .Select(s => new Status()
       {
         // If database is storing 'draft' (as a varchar)
         StatusID=Enum.Parse(typeof(MyStatusID), s.StatusID),
         StatusDescription=s.StatusDesc
       });
}

或者

public static IList<Status> GetAdminStatuses()
{
  IQueryable<Status> stat=context.tblAdminStatus
       .Where(s => s.InactiveDate > DateTime.Now || s.InactiveDate == null)
       .Select(s => new Status()
       {
         // If database is storing '0' (as a varchar)
         StatusID=(MyStatusID)int.Parse(s.StatusID),
         StatusDescription=s.StatusDesc
       });
}