2011-11-23 29 views
10

Tôi đang cố ép buộc LINQ tạo thành một kết nối bên trong giữa hai bảng. Tôi sẽ đưa ra một ví dụ.Buộc linq để thực hiện các kết nối bên trong

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 ... 
) 

Bây giờ tôi đang làm việc với cơ sở dữ liệu bất thường vì không thể kiểm soát mọi người bị thiếu trong bảng Mọi người nhưng có hồ sơ trong CompanyPositions. Tôi muốn lọc ra CompanyPositions với những người mất tích bằng cách tham gia các bảng.

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

LINQ coi tham gia này là dự phòng và loại bỏ nó khỏi SQL nó tạo ra.

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

Tuy nhiên, nó không thừa trong trường hợp của tôi. Tôi có thể sửa nó như thế này

// 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(); 

Tuy nhiên điều này bây giờ tạo ra một mệnh đề whereless trong SQL của tôi. Là một người tinh khiết nhất tôi muốn loại bỏ điều này. Bất kỳ ý tưởng hoặc thiết kế cơ sở dữ liệu hiện tại buộc tay tôi?

+1

bạn đang sử dụng gì? LINQ to SQL? LINQ to Entities? Thứ gì khác? – svick

+1

Mô hình của bạn có thuộc tính điều hướng không? Nếu có, bạn có thể viết một cái gì đó như 'where pos.Person! = Null'. – svick

+0

Tôi đang sử dụng LinqToSql, tôi đã thử 'where pos.Person! = Null' và 'p.PersonId! = 0' và Linq xóa chúng. Trong trường hợp 'p.PersonId! = 0', nó sẽ thay đổi thành 'pos.PersonId! = 0' gây ấn tượng với tôi ngay cả khi đó không phải là những gì tôi theo sau. – Magpie

Trả lời

2

Kể từ PersonId được khai báo NOT NULL (và tôi cho rằng nó được khai báo là một FK để nhân dân) sau đó tôi không chắc chắn cách bạn có thể có một CompanyPosition với một người không được chỉ định; và LINQ không thể thấy làm thế nào bạn có thể eiter, đó là lý do tại sao như bạn đã quan sát thấy Linq xem xét tham gia dự phòng.

+1

Điều đó có ý nghĩa, cơ sở dữ liệu tôi đang làm việc là một phiên bản phẳng của một bậc thầy lớn hơn và phức tạp hơn nhiều. Chỉ có dữ liệu liên quan đến một sản phẩm được chuyển tiếp đến điều này và than ôi vì các bản ghi thiếu như vậy không có FK, chúng được thực thi trên bản gốc. Trong trường hợp này, người đó đã bị hủy xuất bản nên nó không bị đẩy khỏi chủ nhân. Lý tưởng nhất cũng không phải là CompanyPosition nhưng điều này là ngoài tầm kiểm soát của tôi. Hình như thiết kế db là vấn đề chính ở đây. – Magpie

0

Nếu bạn đang sử dụng LinqToSql, bạn có thể sử dụng LoadWith tương tự như sau:

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

Tôi không biết cách ép buộc LINQ sử dụng kết nối. Nhưng sau đây statment sẽ cung cấp cho bạn kết quả cần thiết.

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

clientside chuyển đổi:

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

More lọc trực tiếp:

from pos in CompanyPositions 
where pos.People.Any() 
select pos 
Các vấn đề liên quan