I created Enum ToFrendlyString function for my enums, but i cant use in 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();
}
}
When i try to use this function in Linq, im getting error
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();
If i make another function in same class, like
private string MyStatusToString(MyEnum status)
{
return status.ToFrendlyString();
}
and change my Linq to use this function, then everything works.
Error
Expression of type 'DAL.MyEnum' cannot be used for parameter of type 'System.Enum' of method 'System.String ToFrendlyString(System.Enum)'
I'm not sure you can use Enum
as the Type for an extension method like that - try this instead. I've taken the liberty of tidying the code up a bit, feel free to ignore those changes :)
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();
}
}
I've added a private, generic class to cache the descriptions for your enum members to avoid lots of runtime use of reflection. It looks a bit odd popping in and out of the class to first cache then retrieve the values, but it should work fine :)
The warning I gave in this answer still applies - the enum value passed to the dictionary isn't validated, so you could crash it by calling ((MyEnum)5367372).ToFrendlyString()
.
I am not sure but it can be that you didn t add the DAL project yet to your current project(Add reference -> projects in solutins -> Dal). Then it might work. (I had a similar issue once and this was my solution)
It seems the problem is that your collection is IQueryable<T>
and the query provider is trying to translate your Select()
into a query string.
One way to avoid that is to perform Select()
in memory using 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();
来源:https://stackoverflow.com/questions/14651624/expression-of-type-myenum-cannot-be-used-for-parameter-of-type