强制linq执行内连接

时间:2011-11-23 13:30:28

标签: c# sql linq linq-to-sql

我试图迫使Linq在两个表之间执行内连接。我举一个例子。

CREATE TABLE [dbo].[People] (
   [PersonId] [int] NOT NULL,
   [Name] [nvarchar](MAX) NOT NULL,
   [UpdatedDate] [smalldatetime] NOT NULL
   ... Other fields ...
)

CREATE TABLE [dbo].[CompanyPositions] (
   [CompanyPositionId] [int] NOT NULL,
   [CompanyId] [int] NOT NULL,
   [PersonId] [int] NOT NULL,
   ... Other fields ...
)

现在我正在使用不寻常的数据库,因为我无法控制人们在People表中丢失但在CompanyPositions中有记录的原因。我希望通过加入表来过滤掉缺少人员的CompanyPositions。

return (from pos in CompanyPositions
        join p in People on pos.PersonId equals p.PersonId
        select pos).ToList();

Linq认为此连接是冗余的,并将其从它生成的SQL中删除。

SELECT 
[Extent1].[CompanyPositionId] AS [CompanyPositionId], 
[Extent1].[CompanyId] AS [CompanyId], 
.... 
FROM  [dbo].[CompanyPositions] AS [Extent1]

然而,在我的情况下,它并不多余。我可以像这样解决它

// The min date check will always be true, here to force linq to perform the inner join
var minDate = DateTimeExtensions.SqlMinSmallDate;

return (from pos in CompanyPositions
        join p in People on pos.PersonId equals p.PersonId
        where p.UpdatedDate >= minDate
        select pos).ToList();

然而,这现在在我的SQL中创建了一个不必要的where子句。作为一个最纯粹的我想删除它。任何想法或当前的数据库设计是否与我联系?

4 个答案:

答案 0 :(得分:2)

由于PersonId被声明为NOT NULL(并且我认为它被声明为人民币的FK),所以我不确定如何将一个CompanyPosition与未分配的人一起;而Linq看不出你怎么能这样做,这就是为什么你看到Linq认为连接是多余的。

答案 1 :(得分:0)

如果您使用的是LinqToSql,则可以使用与此类似的LoadWith:

var context = new MyDataContext();
var options = new DataLoadOptions();
options.LoadWith<People>(x => x.CompanyPositions);
context.LoadOptions = options;

答案 2 :(得分:0)

我不知道如何强制linq使用连接。但是下面的陈述应该会给你所需的结果。

return (from pos in CompanyPositions
        where (p in People select p.PersonId).Contains(pos.PersonId)
        select pos).ToList();

答案 3 :(得分:0)

ClientSide转换:

(
from pos in CompanyPositions
join p in People on pos.PersonId equals p.PersonId
select new {pos, p}
).ToList().Select(x => x.pos);

更直接的过滤:

from pos in CompanyPositions
where pos.People.Any()
select pos