【问题标题】:Fastest, cleanest way in linq to exclude elements from other type (+ef)linq 中从其他类型中排除元素的最快、最干净的方法 (+ef)
【发布时间】:2013-06-27 20:58:58
【问题描述】:

假设我们有这两个类:

class GenericFoo
{
   public Guid ID;
   ...
}

class SpecialFoo
{
   public Guid ID;
   public Guid GenericFooID;
   ...
}

GenericFoo 是一种模板类,可以从中创建 SpecialFoos。

现在,我有一个DbSet<GenericFoo> g 和一个DbSet<SpecialFoo> s。 任何 SpecialFoo.GenericFooID 可能存在于 g 中,但也可能缺失。 (例如,GenericFoo 可能已被删除)。当然,反之亦然。

我想要的是调用那些缺少匹配 GenericFooID 的调用,例如:

missing = s.Except(g)

这不起作用,因为 except 仅适用于相同的类。现在我已经通过使用一个相当人为的解决方案解决了这个问题:

ExistingIds = g.Select(f=>f.ID);
missing = s.Where(f => !ExistingIds.Contains(s.GenericFooID));

这里的一个主要缺点是我们失去了类型安全性(如果有人输入错误 g 并指定了类似的类,则无法检查这一点)。 我更喜欢IComparer<type1, type2> 这样的东西,这样Except 调用就可以工作了。

我发现的其他选项是

  • 使用组连接进行“假左连接”,并仅保留不匹配
  • 将第一个转换为字典、哈希表等,只是为了加快速度
  • 试图创建一个通用->特殊转换器,然后是一个 IComparer,只是为了使用Except

我的问题是:

  1. 有没有更好的方法来解决这个问题,只讨论 linq to objects?
  2. 在实体框架的上下文中,解决此问题的最快方法是什么?

【问题讨论】:

  • 那又如何,是 LINQ2Objects 还是 EF?
  • 嗯,它有那么大的不同吗?问题 1 为 L2O,问题 2 为 EF。
  • 那你为什么有一个DBSet?此外,L2O 还开放了诸如 MoreLINQ 之类的东西。
  • 对不起,如果我不清楚。我想我在你有机会看到之前编辑了我的回复。现在,如果我们可以仅使用 L2O 就可以使这变得既漂亮又快速,那么我当然可以只获取所有内容并在本地完成;极不可能,自然。我希望在任何情况下都能找到最好看的解决方案,并为我的具体情况提供最快的解决方案。
  • 不应该 specialFoo 继承自 genericFoo 吗?

标签: c# linq entity-framework linq-to-objects


【解决方案1】:

现在,这是一个很长的镜头,因为它非常深奥,但您想要一个由没有实际关系的人过滤的外连接。你可以试试:

from specialFoo in context.SpecialFoos
join genericFoo in context.GenericFoos 
     on specialFoo.GenericFooID equals genericFoo.ID 
     into gj
where !gj.Any()
select specialFoo;

【讨论】:

  • 是的,这是我的“其他建议”中的第一个,但表达得更清楚。仍然不是一个非常干净的解决方案,imo。
【解决方案2】:

这可能适用于两种情况:

var missing = s.Where(a => !g.Any(b => b.ID == a.GenericFooID));

【讨论】:

  • Where + !Any 效率不高。
  • 它将在 SQL 中生成 Exists 语句。由于我们正在处理密钥,所以应该没问题。
  • 问题是,由于OP的标签不好,我们不知道是L2O还是EF。
  • 问题以询问 LinqtoObjects 和 EF 结束。
  • 现在,这看起来效率低下,但是当谈到 EF 时,我已经开始不相信我的直觉了。不过有一件事:a.GenericFooID 不是键,既不是主键也不是外键。那会有什么不同吗?
猜你喜欢
  • 2017-01-08
  • 1970-01-01
  • 2011-03-12
  • 2011-06-28
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 2018-04-11
  • 2015-06-19
相关资源
最近更新 更多