嵌套.Select()在.Where()里面

时间:2013-11-26 10:29:16

标签: c# sql linq

我在游戏和流派的表之间有多对多的关系。在分析过程中,我需要从游戏中获取符合特定条件的项目。

问题是,为了检查这个标准,我需要分析这个特定游戏的类型。而linq不会让我这样做。

我的请求现在看起来像这样:

var result = GDB.Games.Where((g)=>
  g.GamesToGenres.Select((gtg)=>
    (weights.ContainsKey(gtg.Genre.Name) ? weights[gtg.Genre.Name]:0.0)
  ).Sum() > Threshhold
).ToArray();

当我执行它时,我收到SQL异常

  

当选择列表中只能指定一个表达式时   子查询不是用EXISTS引入的。

有解决方法吗?我怎样才能在Where里面进行选择?

编辑:weightsDictionary<string, double>

编辑:我正在玩lambdas,发现他们的行为很奇怪: 这段代码不起作用,将nvarchar抛给float转换异常:

Func<string, double> getW = (name) => 1;
var t = GDB.Games.Where((g)=>
  g.GamesToGenres.Select((gtg)=>
    getW(gtg.Genre.Name)
  ).Sum() > Threshhold
).ToArray();

但是这个会很好用:

var t = GDB.Games.Where((g)=>
  g.GamesToGenres.Select((gtg)=>
    1
  ).Sum() > Threshhold
).ToArray();

这使我得出结论,linq lambdas 通常的lambdas。那么他们怎么了?它们的局限是什么?我能做什么,我不能做什么呢?为什么我可以在lambda中放置一个.select调用,而不是我自己调用getW?

解决。请参阅以下答案。长话短说,C#除非明确告知,否则不能进入clojures。如果有人知道更好的答案,我仍然感到困惑。

3 个答案:

答案 0 :(得分:2)

您的问题是您正在尝试从应用程序中存在的字典weights中选择某些内容,而不是在数据库中。如果是对您的数据库进行查询的结果,请在其位置使用query.Single(...)

答案 1 :(得分:0)

好吧,我感到困惑超乎想象。以下代码完美无缺:

Func<Game, bool> predicate = (g) =>
  g.GamesToGenres.Select((gtg) =>
    (weights.ContainsKey(gtg.Genre.Name) ? weights[gtg.Genre.Name] : 0.0)
  ).Sum() > Threshhold;

var t = GDB.Games.Where(predicate).ToArray();
细心的读者可能会想说“嘿!这不是你在问题中写的那个代码吗?你只是明确地将它分配给一个变量!”,他就是对的。现在看起来C#lambda处理器似乎是一块东西,它只在你明确声明一个lambda时创建了clojure。如果有人可以向我描述这种现象,我将感激不尽,因为现在我比新生婴儿更困惑。

答案 2 :(得分:0)

LINQ allows您将SQL数据与本地数据(如词典等)组合在一起,只有一个限制。您需要先从SQL中选择数据。这意味着如果用 GDB.Games.ToList()替换 GDB.Games.Where ,您的代码将会起作用。其中。您可以询问性能,但是您可以选择一些数据,如GameId,流派名称等。然后过滤掉游戏。然后按游戏ID列表返回完整游戏信息的结束列表。