我试图迫使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子句。作为一个最纯粹的我想删除它。任何想法或当前的数据库设计是否与我联系?
答案 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