일대 다 관계를 쿼리하려고하지만이를 수행하는 방법을 찾을 수 없습니다. 내가 가지고있는 문제는 조인 테이블 (기본 테이블이 아님)에 살고 싶은 필드의 ID입니다 ...EF 4.3 코드 첫 번째 - 탐색 속성 뒤로 쿼리
설명하기보다는 설명하기가 쉽습니다 !! 내가 가진
두 클래스는 내가 노출하는 저장소는 클라이언트가 I이 결합을하고
public ObservableCollection<DbClient> Clients
{
get { return context.Clients.Local; }
}
을 즉 한
public class DbUserClient
{
public virtual string UserId { get; set; }
public virtual int ClientId { get; set; }
public virtual DateTime AssignedOn { get; set; }
public virtual DateTime? ClearedOn { get; set; }
// navigation properties
public virtual DbUser User { get; set; }
public virtual DbClient Client { get; set; }
}
프로그램에서
public class DbClient
{
public virtual int ClientId {get;set;}
public virtual string EntityName { get; set; }
public virtual bool Deleted { get; set; }
// navigation properties
public ICollection<DbUserClient> UserClients { get; set; }
}
있는 이것이 "로컬"컬렉션을 새로 고침하기 때문에 클라이언트를 통해 쿼리하는 데 열중하고 있습니다. 그러나 나는 "Where"절을 추가 할뿐만 아니라 UserClients를 포함하는 방법을 찾아 낼 수 없다.
context.Clients.Include 같은
내가 시도 뭔가 (C => c.UserClients.Where (UC => uc.UserId == "ME")); .
그러나 이것은 다음과 같은 예외 결과 "(가) 포함 경로 표현 유형에 정의 된 탐색 속성을 참조 참조 탐색 속성과 컬렉션을 탐색 속성에 대한 선택 운영자 점 경로를 사용합니다 매개 변수 이름을 :. 경로를 "
이 작동하지만, 불행히도 내 업데이트되지 않습니다"로컬 "모음 내가 잘못 갔을 경우에
from c in context.Clients
from uc in c.UserClients
where uc.ClientId == uc.ClientId && uc.UserId == "ME"
select new { c.ClientId, c.EntityName, uc.AssignedOn };
어떤 제안?
건배 복근
편집 I : SQL 프로파일 러에서 위의 쿼리를 찾고이 매우 간단하고 더 많거나 적은 내가 무엇을 것의 라인을 따라입니다
SELECT
[Extent1].[ClientId] AS [ClientId],
[Extent1].[EntityName] AS [EntityName],
[Extent2].[AssignedOn] AS [AssignedOn]
FROM [dbo].[Client] AS [Extent1]
INNER JOIN [dbo].[UserClient] AS [Extent2] ON [Extent1].[ClientId] = [Extent2]. [ClientId]
WHERE ([Extent2].[ClientId] = [Extent2].[ClientId]) AND (N'ME' = [Extent2].[UserId])
다음과 같은 SQL을 생성 SQL을 수작업으로 작성했다면 스스로 작성했습니다
그러나 아래의 제안 된 표현이 작동하고 로컬 캐시가 채워지는 것처럼 보일 수도 있습니다
context.Clients
.Where(c => c.UserClients.Any(uc => uc.UserId == userId))
.Select(c => new { DbClient = c, DbUser = c.UserClients.Where(uc => uc.UserId == userId).FirstOrDefault() }).ToList();
다음 SQL을 생성합니다. , 내 요구 사항을 충족 할 것 해결책을 찾았 더 일부 주위에 재생 후 : 그것을 할 필요가 나는 성능에 영향
exec sp_executesql N'SELECT
[Filter2].[ClientId] AS [ClientId],
[Filter2].[EntityName] AS [EntityName],
[Filter2].[Deleted] AS [Deleted],
[Limit1].[UserId] AS [UserId],
[Limit1].[ClientId] AS [ClientId1],
[Limit1].[AssignedOn] AS [AssignedOn],
[Limit1].[ClearedOn] AS [ClearedOn]
FROM (SELECT [Extent1].[ClientId] AS [ClientId], [Extent1].[EntityName] AS [EntityName], [Extent1].[Deleted] AS [Deleted]
FROM [dbo].[Client] AS [Extent1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM [dbo].[UserClient] AS [Extent2]
WHERE ([Extent1].[ClientId] = [Extent2].[ClientId]) AND ([Extent2].[UserId] = @p__linq__0)
)) AS [Filter2]
OUTER APPLY (SELECT TOP (1)
[Extent3].[UserId] AS [UserId],
[Extent3].[ClientId] AS [ClientId],
[Extent3].[AssignedOn] AS [AssignedOn],
[Extent3].[ClearedOn] AS [ClearedOn]
FROM [dbo].[UserClient] AS [Extent3]
WHERE ([Filter2].[ClientId] = [Extent3].[ClientId]) AND ([Extent3].[UserId] = @p__linq__1)) AS [Limit1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'ME',@p__linq__1=N'ME'
EDIT II를해야합니다 가정입니다보다이 많이 더 복잡 보인다. SQL 프로파일 러를 살펴보면 생성 된 SQL에 만족합니다. 이는 원래 검색어와 유사합니다.
여기에 관련된 지연로드가 없다고 가정합니다.
var clients = context.Clients
.Where(c => c.UserClients.Any(uc => uc.UserId == "ME"))
.ToList();
이 올바른 클라이언트를로드하지만 사용자가 포함되어 있지 않습니다 : 누군가가 내가 감사 드리겠습니다 확인할 수 있다면
context.Clients.Join
(
context.UserClients,
c => c.ClientId,
uc => uc.ClientId,
(user, usrclient) => new { DbClient = user, DbUserClient = usrclient }
).Where(uc => uc.DbUserClient.UserId == userId).Load();
시간을내어 주셔서 감사합니다. 내가 가장 좋은 방법은 내 원래 게시물에 수정 섹션을 추가 한 제안에 대한 의견을 말할 수 있는지 아니었다. 당신이 그것을 들여다 볼 수 있다면 제게 당신의 생각을 알려주세요. – user1460473
@ user1460473 : 간단한 답을 편집 섹션에 추가했습니다. – Slauma
그냥 완벽 :) – user1460473