我有一个简单的类,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/