C# LINQ to Entity:在“选择”部分使用包含会引发意外错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/802159/
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-05 01:46:07  来源:igfitidea点击:

LINQ to Entity: using Contains in the "select" portion throws unexpected error

c#entity-frameworklinq-to-entities

提问by bugfixr

I've got a LINQ query going against an Entity Framework object. Here's a summary of the query:

我有一个针对实体框架对象的 LINQ 查询。以下是查询的摘要:

//a list of my allies
List<int> allianceMembers = new List<int>() { 1,5,10 };

//query for fleets in my area, including any allies (and mark them as such)
var fleets = from af in FleetSource
             select new Fleet 
             {
                 fleetID = af.fleetID,
                 fleetName = af.fleetName,
                 isAllied = (allianceMembers.Contains(af.userID) ? true : false)
             };

Basically, what I'm doing is getting a set of fleets. The allianceMembers list contains INTs of all users who are allied with me. I want to set isAllied = true if the fleet's owner is part of that list, and false otherwise.

基本上,我正在做的是获得一组舰队。AllianceMembers 列表包含所有与我结盟的用户的 INT。如果舰队的所有者是该列表的一部分,我想设置 isAllied = true,否则设置为 false。

When I do this, I am seeing an exception: "LINQ to Entities does not recognize the method 'Boolean Contains(Int32)' method"

当我这样做时,我看到一个异常:“LINQ to Entities 无法识别‘Boolean Contains(Int32)’方法”

I can understand getting this error if I had used the contains in the where portion of the query, but why would I get it in the select? By this point I would assume the query would have executed and returned the results. This little ditty of code does nothing to constrain my data at all.

如果我在查询的 where 部分使用了 contains ,我可以理解得到这个错误,但为什么我会在选择中得到它?此时,我会假设查询已执行并返回结果。这段小小的代码根本没有限制我的数据。

Any tips on how else I can accomplish what I need to with setting the isAllied flag?

关于如何通过设置 isAllied 标志来完成我需要的任何提示?

Thanks

谢谢

采纳答案by pomarc

var fleets = from af in FleetSource;

var x = from u in fleets.ToList()
                         select new Fleet
                         {
                            fleetID = u.fleetID,
                            fleetName = u.fleetName,
                            isAllied = (allianceMembers.Contains(u.userID) ? true : false)
                         }

calling ToList()on fleets the query is executed, later you can use Contains().

调用ToList()队列执行查询,稍后您可以使用Contains().

回答by MaSuGaNa

This poached from a previous answer...

这是从以前的答案中挖出来的......

Contains not supported.

包含不支持。

IN and JOIN are not the same operator (Filtering by IN never changes the cardinality of the query).

IN 和 JOIN 不是同一个运算符(按 IN 过滤永远不会改变查询的基数)。

Instead of doing it that way use the join method. It's somewhat difficult to understand without using the query operators, but once you get it, you've got it.

而不是这样做,使用 join 方法。不使用查询运算符有点难以理解,但是一旦你掌握了它,你就掌握了它。

var foo = 
model.entitySet.Join(  //Start the join
values, //Join to the list of strings
e => e.Name, // on entity.Name
value => value, //equal to the string
(ModelItem ent, String str) => ent);//select the entity

Here it is using the query operators

这里使用的是查询运算符

var foo = from e in model.entitySet
join val in values on
e.Name equals val
select e;

回答by Ronald Wildenberg

Basically the entity framework attempts to translate your LINQ query into a SQL statement but doesn't know how to handle the Contains.

基本上,实体框架尝试将您的 LINQ 查询转换为 SQL 语句,但不知道如何处理Contains.

What you can do instead is retrieve your fleets from the database and set the isAllied property later:

您可以做的是从数据库中检索您的车队并稍后设置 isAllied 属性:

var fleets = (from af in FleetSource
              select new Fleet 
              {
                  fleetID = af.fleetID,
                  fleetName = af.fleetName,
                  userId = af.userId
              }).AsEnumerable();

foreach (var fleet in fleets)
{
    fleet.isAllied = (allianceMembers.Contains(fleet.userID) ? true : false);
}

回答by Lewis

Everyone above me is wrong!!! (No offense ...) It doesn't work because you are using the IList overload of "Contains" and not the IEnumerable overload of "Contains". Simply change to:

我上面的人都错了!!!(无意冒犯...)它不起作用,因为您使用的是“包含”的 IList 重载,而不是“包含”的 IEnumerable 重载。只需更改为:

allianceMembers.Contains<int>(af.userID)

By adding the <int>, you are telling the compiler to use the IEnumerable overload instead of the IList overload.

通过添加<int>,您告诉编译器使用 IEnumerable 重载而不是 IList 重载。