2

単純なStatusのクラスがあり、2つのプロパティが含まれています。マジックストリングの束を排除できるように、Properties(StatusID)の1つに列挙型を使用したいと思います。

私の質問は、それをどのように操作するかです。たとえば、次のようなドロップダウンボックスにバインド用のリストを返すメソッドがあります->

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.StatusIDDBが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 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

4 に答える 4

1

あなたが探しているものではありませんか?

 Colors colorValue = (Colors) Enum.Parse(typeof(Colors), colorString);
于 2012-07-11T20:01:37.403 に答える
1

私はあなたが探しているものは次のとおりだと思います:

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

.Net 4.0にもありますEnum.TryParse(string, out enum)が、それはあなたの内部ではあまり役に立ちません.Select()

または 、ほとんどの場合効率は低下しますが、を文字列として保持し、列挙値をその場で出力Status.StatusIDする読み取り専用プロパティを追加できます。StatusEnum

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

この代替手段は、instance.StatusEnumが読み取られるたびに値を再解析するため、LINQが最初のアプローチを嫌う場合を除いて、この方法はお勧めしません。


最後の編集への応答:

Enum.Parse()は、例ではSQLに正常に変換されています。.Where()問題は、と比較する句を追加するswitchステートメントにありますEnum。LINQはEnum == EnumSQLに変換する方法を知りませんが、C#オブジェクトでそれを行う方法は知っています。したがって、最も簡単な解決策は、それらをToList()して、ローカルで比較することです。残念ながら、これは、データベースから-all-ステータスタイプの行をダウンロードし、それらをローカルでフィルタリングすることを意味します。何百万ものレコードがある場合、これは合理的ではない可能性があります。

   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;
        }
    }
于 2012-07-11T20:04:43.200 に答える
0

バッキングフィールド*をにするintと、問題なく動作します。

実際、byte列挙型を使用することもできます(smallintバッキングフィールドを使用)。

ただし、設計者に問題があります。IIRC、enum宣言は同じ名前空間にある必要があります。

注:バッキングフィールドとは、データベーステーブルの列タイプを意味します。

于 2012-07-11T19:58:10.367 に答える
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
       });
}
于 2012-07-11T20:02:52.270 に答える