题
我有像这样的Linq to Entities查询:
var results = from r in entities.MachineRevision
where r.Machine.IdMachine == pIdMachine
&& r.Category == (int)pCategory
select r;
通常,我使用下面的代码检查是否返回了一些结果:
if (results.Count() > 0)
{
return new oMachineRevision(results.First().IdMachineRevision);
}
但是,我在 if 条件中收到 NotSupportedException 。
错误消息是:无法创建类型为“Closure type”的常量值。在此上下文中仅支持原始类型(例如Int32,String和Guid')。
请注意, pCategory 是枚举类型。
解决方案
编辑:根据您的更新,错误可能与实体类中的枚举有关。有关详细信息和工作,请参阅此博客条目 -周围。我将原始答案作为对查询语法的改进。
尝试使用FirstOrDefault选择查询本身中的第一个实体,然后检查结果是否为null。
int compareCategory = (int)pCategory; // just a guess
var result = (from r in entities.MachineRevision
where r.Machine.IdMachine == pIdMachine
&& r.Category == compareCategory
select r).FirstOrDefault();
if (result != null)
{
return new oMachineRevision(result.IdMachineRevision);
}
其他提示
为什么不直接使用FirstOrDefault()并检查null?我无法看到查询计数然后获取第一个元素的好处。
在linq的标准实现中,运算符<!> quot; select <!> quot;和<!>“;其中<!>”;映射到返回IEnumerable或IQueryable的方法。因此,使用标准linq方法时,应始终从查询中返回IEnumerable而不是单个对象。
但linq运算符的候选linq方法并不局限于返回IEnumerables的方法,任何返回任何内容的方法都可以选择。
如果您有名为<!>的实例方法,请选择<!>“;和<!>“;其中<!>”;返回特定于您的类的单个对象或扩展方法,并返回单个对象,而不是标准的linq对象。
我的猜测是<!>“;选择<!>”;或<!>“;其中<!>”;在您的类中定义的方法是使linq返回单个值而不是IEnumerable<T>
。
我不知道根据查询结果会创建不同的匿名对象。我猜他们只是希望结果是IEnumerable类型
如何使用foreach?
var results = from r in entities.MachineRevision
where r.Machine.IdMachine == pIdMachine
&& r.Category == pCategory
select r;
foreach( var r in results )
{
yield return new oMachineRevision( r.IdMachineRevision );
}
这也适用于所有隐式类型。我必须承认我一直忘记这一点,这就是我发现这篇文章的方式。
如果你有
class ClassA {
...
private string value;
...
public static implicit operator string(ClassA value)
{
return value.ToString();
}
...
}
你需要明确地将类强制转换为astring以进行比较。
所以我通常会这样做
var myClassAStr = myClassA.ToString();
var x = (from a in entites where a.ValToCompare == myClassAStr select a).first();
// do stuff with x
...
尝试使用
IENumerable<MachineRevision> results = from r in entities.MachineRevision
...
代替。
我认为它导致了你的问题。
编辑:
阅读错误消息。 <!>“无法创建”闭包类型“类型的常量值。在此上下文中仅支持基本类型(例如Int32,String和Guid')。<!> quot;
其中一个比较是使用非int,string或guid的类型。我猜这个类别。
r.Machine.IdMachine == pIdMachine && r.Category == pCategory
有趣的是,LinqToSql将允许这种构造。不知道为什么LinqToEntities不支持这个。
我认为你也可以通过使用lambda表达式选择你想要的另一种更简单的方法。
var result = entities.MachineRevision
.Where(x => x.Machine.IdMachine == pIdMachine)
.Where(y => y.Category == (int)pCategory)
.FirstOrDefault();
if (result != null)
{
return new oMachineRevision(result.IdMachineRevision);
}
然后按照正常情况继续进行