Linq和Repository模式 - 没有得到如何应用Join方法

时间:2011-08-10 14:02:42

标签: c# linq

我知道这很简单,但我无法理解这一点。给出类似于的查询:

SELECT * FROM Client
LEFT JOIN DriverClient ON DriverClient.ClientID = Client.ClientID
WHERE Client.FullName LIKE '%Tooley%' 
AND (DriverClient.DriverID IS NULL OR DriverClient.DriverID <> 1)

和一个存储库模式,我将如何在Linq中实现与此近似的内容?

我想像LIKE想的那样,它是DriverClient.DriverID上的过滤器,我无法理解。这显然会涉及IEnumerable<T>.Join,但是这个的语法让我感到厌烦,我不能自己写一个好例子,每个人似乎都使用Linq Query语法,或者预先填充集合的示例,而不是{ {1}}。

5 个答案:

答案 0 :(得分:2)

虽然LINQ中有一个join结构,但通常不需要它。在关系数据库中使用JOIN查询的关系在OO编程中呈现属性(单个对象或集合中的任一个)。看起来你应该在你的映射中使用DriverClient.Clients或类似的东西,并使用它来代替连接。

答案 1 :(得分:0)

这个链接可能很有用http://msdn.microsoft.com/en-us/vcsharp/ee908647#leftouterjoin,它描述了如何使用预先填充的集合进行左连接,但是使用IQueryable它是相同的 http://msdn.microsoft.com/en-us/vcsharp/aa336746 - 这里有很多有用的例子

答案 2 :(得分:0)

试一试:

var Client = new[] { new { ClientID = 1, FullName = "Name1" }, new { ClientID = 2, FullName = "Name2_Tooley_3242343" } };
var DriverClient = new[] { new { ClientID = 2, DriverID = 20 }, new { ClientID = 3, DriverID = 30 } };

var result =
    from client in Client
    join driver in DriverClient on client.ClientID equals driver.ClientID into ClientDriver
    from clientDriver in ClientDriver.DefaultIfEmpty()
    where client.FullName.Contains("Tooley") && (clientDriver == null || clientDriver.DriverID != 1)
    select client;

<强>更新

var result2 = Client
  .GroupJoin(DriverClient, client => client.ClientID, driver => driver.ClientID, (client, drivers) => new { client, drivers })
  .Where(clientDrivers => clientDrivers.client.FullName.Contains("Tooley") && clientDrivers.drivers.Count(driver => driver.DriverID != 1) > 0);

答案 3 :(得分:0)

在不知道您的数据库结构的情况下,其中一些是猜测。

看起来DriverClient是一个简单的链接表,对吗?列DriverIDClientID,仅用于将驱动程序链接到客户端?假设这意味着你有一个*到多对的关系(一个司机有很多客户;看起来很合理),你可能正在寻找这样的东西:

var result = DB.Clients
    .Where(c => c.FullName.Contains("Tooley")
        && (c.DriverID == null || c.DriverId != 1));

通常,LINQ会尝试隐藏连接和事物的细节。相反,你会得到导航属性等内容。

答案 4 :(得分:0)

这里的关键是你如何处理上下文。如果每个“客户端”在您的存储库中管理它自己的上下文,您将无法跨上下文加入。但是,如果所有存储库使用相同的底层上下文(通过DI),那么只要您将存储库中的对象公开为IQueryable而不是IEnumerable / IList / etc,就应该能够使用查询或lambda语法连接它们。 / p>