我有一个自定义属性,用于存储枚举项目的显示名称。我编写了一个Extension方法,该方法返回Enum自定义属性显示名称。
我在LINQ查询中使用扩展方法。但是输出很奇怪。当我在尚未运行的查询中调用我的扩展方法时,它将返回,Enum is null
但是当我在.ToList()
被调用的查询中运行它时,它可以正常工作(请参见输出)……它们之间有什么区别?为什么在我的查询不运行时enum为null。
注意:我是LINQPAD。
void Main()
{
Console.WriteLine(((ProductStatuses)0).GetTitle());
Console.WriteLine(((ProductStatuses)1).GetTitle());
Console.WriteLine(((ProductStatuses)3).GetTitle());
var query_01 = (from item in SH_Products
select new
{
Status = item.Status,
StatusText = ((ProductStatuses)item.Status).GetTitle(),
});
var query_02 = (from item in SH_Products.ToList()
select new
{
Status = item.Status,
StatusText = ((ProductStatuses)item.Status).GetTitle(),
});
query_01.Dump();
query_02.Dump();
}
public static class ExtensionMethods
{
public static string GetTitle(this Enum enm)
{
if (enm == null)
{
return "Enum is null";
}
var type = enm.GetType();
var members = type.GetMembers(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
foreach (var item in members)
{
if (enm.ToString() == item.Name)
{
var attributes = item.GetCustomAttributes(typeof(FaraDisplay), false);
var attribute = String.Empty;
if (attributes.Length == 0)
attribute = item.Name;
else
attribute = ((FaraDisplay)attributes.Single()).GetName();
return attribute;
}
}
throw new InvalidEnumArgumentException();
}
}
public enum ProductStatuses
{
[FaraDisplay("Inactive Product")]
Inactive = 0,
[FaraDisplay("Available Product")]
Available = 1,
[FaraDisplay("ComingSoon Product")]
ComingSoon = 2,
[FaraDisplay("UnAvailable Product")]
UnAvailable = 3,
[FaraDisplay("OrderRegister Product")]
OrderRegister = 4
}
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class FaraDisplay : Attribute
{
private readonly string _name;
public FaraDisplay(string name)
{
_name = name;
}
public string GetName()
{
return _name;
}
}
输出:
无效产品
可用产品
不可用产品
Enum为空
Enum为空
Enum为空
Enum为空
Inactive Product
可用产品
不可用产品
不可用产品
实际上,问题是linq to sql不知道如何转换GetTiltle()
为sql语句,因此它跳过了它。调用时ToList()
,您正在使用linq来处理对象,因此它可以按预期工作,因为那时候它只是普通的.net。
所有linq提供程序(实体框架,nhibernate等)都具有相同的问题,尽管您会看到实体框架抛出异常,也许还会抛出nhibernate。
没有基于您正在做的事情的解决方法,因此一旦在内存中存储了对象,就只需要执行该计算即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句