我为我的枚举创建了Enum ToFrendlyString函数,但我无法在Linq中使用。
public enum MyEnum
{
Queued = 0,
[Description("In progress")]
In_progress = 2,
[Description("No answer")]
No_answer = 6,
}
public static class EnumToFrendlyString
{
public static string ToFrendlyString(this Enum value)
{
return value.GetEnumDescription();
}
public static string GetEnumDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
var attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}
}
当我尝试在Linq中使用此功能时,我得到错误
var res = collection.AsQueryable().Where(p => p.UserID == UserID).OrderByDescending(p=> p.DateCreated).Select(p => new MyClass
{
Date = p.DateCreated.ToString(),
Status = p.Status.ToFrendlyString(),
}).Take(10).ToList();
如果我在同一个类中创建另一个函数,比如
private string MyStatusToString(MyEnum status)
{
return status.ToFrendlyString();
}
并更改我的Linq以使用此功能,然后一切正常。
错误
Expression of type 'DAL.MyEnum' cannot be used for parameter of type 'System.Enum' of method 'System.String ToFrendlyString(System.Enum)'
答案 0 :(得分:2)
我不确定您是否可以使用Enum
作为此类扩展方法的类型 - 请尝试此操作。我冒昧地整理了一些代码,随意忽略这些变化:)
public static class EnumToFrendlyString
{
public static string ToFrendlyString<T>(this T value)
where T : struct
{
return value.GetEnumDescription();
}
public static string GetEnumDescription<T>(this T value)
where T : struct
{
return EnumDescriptionCache<T>.Descriptions[value];
}
private static class EnumDescriptionCache<T>
where T : struct
{
public static Dictionary<T, string> Descriptions =
Enum.GetValues(typeof(T))
.Cast<T>()
.ToDictionary(
value => value,
value => value.GetEnumDescriptionForCache());
}
private static string GetEnumDescriptionForCache<T>(this T value)
where T : struct
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Only use with enums", "value");
}
var descriptionAttribute = typeof(T)
.GetField(value.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.Cast<DescriptionAttribute>()
.FirstOrDefault();
return (descriptionAttribute != null)
? descriptionAttribute.Description
: value.ToString();
}
}
我添加了一个私有的泛型类来缓存枚举成员的描述,以避免大量运行时使用反射。它看起来有点奇怪弹出进出第一个缓存然后检索值,但它应该工作正常:)
我在this answer中发出的警告仍然适用 - 传递给字典的枚举值未经过验证,因此您可以通过调用((MyEnum)5367372).ToFrendlyString()
使其崩溃。
答案 1 :(得分:0)
我不确定但是你可能还没有将DAL项目添加到你当前的项目中(添加参考 - &gt; solutins中的项目 - &gt; Dal)。然后它可能会工作。 (我有一个类似的问题,这是我的解决方案)
答案 2 :(得分:0)
问题似乎是您的收藏集是IQueryable<T>
,而查询提供商正在尝试将您的Select()
转换为查询字符串。
避免这种情况的一种方法是使用Select()
在内存中执行IEnumerable<T>
:
var res = collection.AsQueryable()
.Where(p => p.UserID == UserID)
.OrderByDescending(p=> p.DateCreated)
.Take(10)
.AsEnumerable()
.Select(p => new MyClass
{
Date = p.DateCreated.ToString(),
Status = p.Status.ToFrendlyString(),
})
.ToList();