C# Linq 返回列表或单个对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/400100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:58:21  来源:igfitidea点击:

Linq returns list or single object

c#linq.net-3.5enums

提问by Nelson Reis

I have a Linq to Entities query like this one:

我有一个像这样的 Linq to Entities 查询:

var results = from r in entities.MachineRevision
              where r.Machine.IdMachine == pIdMachine
                 && r.Category == (int)pCategory
              select r;

Usually, I use the code below to check if some results are returned:

通常,我使用下面的代码来检查是否返回了一些结果:

if (results.Count() > 0)
{
    return new oMachineRevision(results.First().IdMachineRevision);
}

However, I'm getting NotSupportedExceptionin the ifcondition.

但是,我在if条件下收到NotSupportedException

The error message is: Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

错误消息是:无法创建类型为“闭包类型”的常量值。在此上下文中仅支持原始类型(“例如 Int32、String 和 Guid”)。

Note that pCategoryis an Enum type.

请注意,pCategory是 Enum 类型。

采纳答案by tvanfosson

EDIT: Based on your update, the error may be related to an enum in your entity class. See this blog entryfor more information and a work-around. I'm leaving my original answer as an improvement on your query syntax.

编辑:根据您的更新,该错误可能与您的实体类中的枚举有关。有关更多信息和解决方法,请参阅此博客条目。我将保留原始答案作为对查询语法的改进。

Try doing the selection of the first entity in the query itself using FirstOrDefault and then check if the result is null.

尝试使用 FirstOrDefault 选择查询本身中的第一个实体,然后检查结果是否为空。

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);
}

回答by NikolaiDante

try using

尝试使用

IENumerable<MachineRevision> results = from r in entities.MachineRevision
...

instead.

反而。

I think its the var that's causing your issue.

我认为是导致您出现问题的 var。

回答by Jon Skeet

Why not just use FirstOrDefault() instead, and check for null? I can't see the benefit in querying for the count and then taking the first element.

为什么不直接使用 FirstOrDefault() 并检查是否为 null?我看不出查询计数然后取第一个元素的好处。

回答by Amy B

Edit:

编辑:

Read the error message. "Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."

阅读错误消息。“无法创建类型为‘闭包类型’的常量值。此上下文中仅支持原始类型(‘例如 Int32、String 和 Guid’)。”

One of these comparisions is with a type that is not int, string or guid. I'm guessing the Category.

这些比较之一是使用不是 int、string 或 guid 的类型。我猜类别。

r.Machine.IdMachine == pIdMachine && r.Category == pCategory

Interestingly, LinqToSql will allow this construction. Don't know why LinqToEntities does not support this.

有趣的是,LinqToSql 将允许这种构造。不知道为什么 LinqToEntities 不支持这个。

回答by Trap

I didn't know different anonymous objects would be created depending on the query result. I guess they just wanted results to be of type IEnumerable

我不知道会根据查询结果创建不同的匿名对象。我猜他们只是希望结果是 IEnumerable 类型的

How about using a foreach?

使用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 );
}

回答by Pop Catalin

In the standard implementation of linq, the operators "select" and "where" map to methods that return an IEnumerable or IQueryable. So standard linq methods when used should always return an IEnumerable from your query not a single object.

在 linq 的标准实现中,运算符“select”和“where”映射到返回 IEnumerable 或 IQueryable 的方法。因此,使用标准 linq 方法时,应始终从查询中返回 IEnumerable 而不是单个对象。

But linq methods that are candidates for the linq operators are not restricted to methods returning IEnumerables, any method returning anything can be chosen.

但是作为 linq 运算符候选的 linq 方法不限于返回 IEnumerables 的方法,可以选择任何返回任何内容的方法。

In case you have instance methods named "Select" and "Where" that return a single object or extensions methods that are specific to your class and return a single object those will be used instead of the standard linq ones.

如果您有名为“Select”和“Where”的实例方法返回单个对象或特定于您的类的扩展方法并返回单个对象,则将使用这些方法而不是标准的 linq 方法。

My guess is that either a "Select" or "Where" method defined in your class is making linq return a single value instead of a IEnumerable<T>.

我的猜测是,在您的类中定义的“Select”或“Where”方法使 linq 返回单个值而不是IEnumerable<T>.

回答by dan richardson

I think you could also select the item you want another, simpler way by using lambda expressions.

我认为您还可以使用 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);
}

and then proceeding as you would normally

然后像往常一样继续

回答by cmon_stoke

This goes for all implicit types too. I must admit I keep forgetting this and that's how I came across this post.

这也适用于所有隐式类型。我必须承认我一直忘记这一点,这就是我看到这篇文章的方式。

if you have

如果你有

class ClassA {
               ...

               private string value;

               ...

               public static implicit operator string(ClassA value)
               {
                    return value.ToString();
               } 

              ...
}

you need to explictly cast the class to astring for comparison.

您需要将类显式转换为字符串以进行比较。

so I usually do this

所以我通常这样做

    var myClassAStr = myClassA.ToString();

    var x = (from a in entites where a.ValToCompare == myClassAStr select a).first();

// do stuff with x
    ...