【问题标题】:Concatenating two queries bases on a foreign key基于外键连接两个查询
【发布时间】:2013-03-21 23:12:41
【问题描述】:

我(至少尝试)在我的 .NET C# 项目中实现 Repository pattern,所以当我需要与数据库通信时,我会这样做:

IList<Sole> soles = SoleService.All().ToList();

作为从服务调用的方法的名称,上面的查询建议我从Sole 表中获取所有记录。我不想,我认为这是实现这种模式的正确方法,在我的服务中保留太多自定义逻辑。我的意思是我只想保留All() 方法,并且对结果的每次修改都在服务方法之外进行。

目前的问题是这样的。我有实体Sole 和实体SoleColorSoleColor 有一个外键列 SoleID 建立两个表之间的关系。现在对于这两个实体,我只能调用 All() 方法:

var soleColors = SoleColorService.All();
var soles = SoleService.All();

但在这里我需要进行一些自定义,即只从Sole 中选择与SoleColor 实体相关的那些行。换句话说,最终只列出了来自Sole 的那些行的列表,其中可以在SoleColor SoleID 外键中找到 Sole.ID 作为外键。

现在我有点困惑 - 自从我上次使用纯 SQL 合成器以来已经有一段时间了。我认为这很容易使用 SQL 和 JOIN 实现。但是当涉及到 LINQ 时,我到目前为止的经验告诉我,我需要这两个查询:

var soleColors = SoleColorService.All();
var soles = SoleService.All();

然后进行某种 JOIN/UNION 以仅过滤我需要的结果。

那么在这种情况下我需要使用哪些工具,因为这不是我需要这个的唯一地方,我想学习自己做,当然是在目前的情况下做?

【问题讨论】:

  • 您使用的是 the LINQ to SQL 还是实体框架?无论如何,正如您所注意到的,您可以查找 IQueryable.JoinIEnumerable.Join,或者 - 在使用 EF 时 - 使用导航属性。 :)
  • 对不起,我什至没想到这一定是个问题。我正在使用 ADO.NET EX - 代码优先方法。
  • 我只是澄清一下,LINQ To SQL 是一个较旧的,而实体框架(使用 LINQ To Entities)是一个新的,而两者的工作方式略有不同.
  • 我认为如果您向我们展示您的 Sole 和 SoleColor 对象会有所帮助...您可能会在那里遗漏一些东西。使用 LINQ,您应该能够以 SoleColorService.All().Where(s =&gt; s.SoleId.HasValue) 为例
  • > 在您需要来自存储库的可变查询,但仍希望在需要时交换 OR 映射器的好处的情况下,IQueryable 是一个强大的工具。看到这个答案:stackoverflow.com/questions/1573658/…

标签: c# linq linq-to-sql


【解决方案1】:

在您的最后评论之后,我认为这就是您要寻找的内容:

from s in SoleService.All()
join sc in SoleColorService.All() on s.ID equals sc.SoleID
select s

但这只有在两个存储库具有相同的上下文实例时才有效。如果没有,您必须分两步完成:

var ids = SoleColorService.All().Select(sc => sc.SoleID).ToArray();
var soles = SoleService.All().Where(s => ids.Contains(s.ID));

我对静态的All() 方法有点怀疑。他们建议您使用静态上下文,这被认为是不好的做法。此外,我想知道这些关联。听上去我希望Sole 有一个SoleColor,即Sole 有一个SoleColorId FK。

【讨论】:

  • 我得到一个错误 - The value can not be null - 即使我看不到究竟是什么取空值。不过,我尝试了这两个示例。
  • 这些SoleIds 是否可以为空?
  • 不,我认为相同的类型是 long 而不是 long? 并且在数据库中它被标记为 NOT NULL
  • 好的,我需要看看发生这个异常的代码。也许您可以将其添加到您的帖子中并标记引发异常的行。
  • 我正在使用第二种解决方案。首先在这一行:var soles = SoleService.All().Where(s =&gt; ids.Contains(s =&gt; s.SoleID)); 这 - (s =&gt; s.SoleID) 被标记为错误,错误是 - Cannot convert lambda expression to type long because it is not a delegate type。我试图用 - ids.Contains(s.ID) 更改它 - 不知道你为什么写 - s.SoleIDSoleID 是 FK,而 s 只是 ID,据我了解代码的含义。到目前为止,您怎么看?
猜你喜欢
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 2021-07-13
  • 2015-07-30
  • 1970-01-01
相关资源
最近更新 更多