我有一个简单的类,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();
}
}
答案 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
});
}