LINQ 및 Lambda와의 결합 / 위치 Lambda로 작성된 쿼리에 문제가 있습니다. 지금까지

LINQ 및 Lambda로 작성된 쿼리에 문제가 있습니다. 지금까지 내 코드에 많은 오류가 발생했습니다.

int id = 1;
var query = database.Posts.Join(database.Post_Metas,
                                post => database.Posts.Where(x => x.ID == id),
                                meta => database.Post_Metas.Where(x => x.Post_ID == id),
                                (post, meta) => new { Post = post, Meta = meta });

LINQ를 처음 사용 하므로이 쿼리가 올바른지 확실하지 않습니다.



답변

SQL 구문에 익숙하다면 LINQ 쿼리 구문을 사용하는 것이 훨씬 명확하고 자연스럽고 오류를 쉽게 발견 할 수 있습니다.

var id = 1;
var query =
   from post in database.Posts
   join meta in database.Post_Metas on post.ID equals meta.Post_ID
   where post.ID == id
   select new { Post = post, Meta = meta };

그래도 람다를 계속 사용하고 있다면 구문이 약간 벗어납니다. LINQ 확장 방법을 사용하는 동일한 쿼리는 다음과 같습니다.

var id = 1;
var query = database.Posts    // your starting point - table in the "from" statement
   .Join(database.Post_Metas, // the source table of the inner join
      post => post.ID,        // Select the primary key (the first part of the "on" clause in an sql "join" statement)
      meta => meta.Post_ID,   // Select the foreign key (the second part of the "on" clause)
      (post, meta) => new { Post = post, Meta = meta }) // selection
   .Where(postAndMeta => postAndMeta.Post.ID == id);    // where statement

답변

이 두 가지 방법으로 갈 수 있습니다. 사용 LINQPad 와 더미 데이터베이스, 나는 다음과 같은 쿼리를 내장 (당신이있는 거 LINQ에 새로운 경우 귀중한를)

Posts.Join(
    Post_metas,
    post => post.Post_id,
    meta => meta.Post_id,
    (post, meta) => new { Post = post, Meta = meta }
)

또는

from p in Posts
join pm in Post_metas on p.Post_id equals pm.Post_id
select new { Post = p, Meta = pm }

이 특별한 경우에는 LINQ 구문이 더 깨끗하다고 ​​생각합니다 (읽기 가장 쉬운 것에 따라 둘 사이에서 변경됩니다).

내가 지적하고 싶은 것은 데이터베이스에 적절한 외래 키 (post와 post_meta 사이)가 있다면 많은 수의 레코드를로드하려고하지 않으면 명시 적 조인이 필요하지 않을 것입니다 . 귀하의 예는 단일 게시물을로드하려고하고 메타 데이터임을 나타냅니다. 각 게시물에 대해 많은 post_meta 레코드가 있다고 가정하면 다음을 수행 할 수 있습니다.

var post = Posts.Single(p => p.ID == 1);
var metas = post.Post_metas.ToList();

n + 1 문제를 피하려면 LINQ to SQL에 모든 관련 항목을 한 번에로드하도록 명시 적으로 지시 할 수 있습니다 (L2S에 더 익숙한 경우 고급 주제 일 수 있음). 아래 예는 “포스트를로드 할 때 ‘Post_metas’속성으로 표시되는 외래 키를 통해 이와 관련된 모든 레코드도로드합니다”라고 말합니다.

var dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Post>(p => p.Post_metas);

var dataContext = new MyDataContext();
dataContext.LoadOptions = dataLoadOptions;

var post = Posts.Single(p => p.ID == 1); // Post_metas loaded automagically

동일한 유형 또는 여러 유형 LoadWith에 대해 단일 세트에서 많은 호출을 수행 할 수 DataLoadOptions있습니다. 이 작업을 많이 수행하면 캐싱을 고려할 수 있습니다.


답변

Daniel은 구문 관계에 대해 잘 설명했지만 팀이 이해하기 쉽도록이 문서를 정리했습니다. 이것이 누군가를 돕기를 바랍니다.


답변

키 선택기가 잘못되었습니다. 해당 테이블 유형의 오브젝트를 가져 와서 조인에 사용할 키를 리턴해야합니다. 나는 당신이 이것을 의미한다고 생각합니다 :

var query = database.Posts.Join(database.Post_Metas,
                                post => post.ID,
                                meta => meta.Post_ID,
                                (post, meta) => new { Post = post, Meta = meta });

나중에 키 선택기의 일부가 아닌 where 절을 적용 할 수 있습니다.


답변

LINQ + EntityFramework를 시작할 때이 예제를 하루 동안 보았습니다.

EntityFramework를 사용 Meta하고 있고 Post모델 객체 에 이름이 지정된 탐색 속성 이 있으면이 작업은 쉽게 수행 할 수 있습니다. 엔터티를 사용 중이고 해당 탐색 속성이 없으면 무엇을 기다리고 있습니까?

database
  .Posts
  .Where(post => post.ID == id)
  .Select(post => new { post, post.Meta });

먼저 코드를 수행하는 경우 속성을 다음과 같이 설정합니다.

class Post {
  [Key]
  public int ID {get; set}
  public int MetaID { get; set; }
  public virtual Meta Meta {get; set;}
}

답변

나는 이와 같은 일을했습니다.

var certificationClass = _db.INDIVIDUALLICENSEs
    .Join(_db.INDLICENSECLAsses,
        IL => IL.LICENSE_CLASS,
        ILC => ILC.NAME,
        (IL, ILC) => new { INDIVIDUALLICENSE = IL, INDLICENSECLAsse = ILC })
    .Where(o =>
        o.INDIVIDUALLICENSE.GLOBALENTITYID == "ABC" &&
        o.INDIVIDUALLICENSE.LICENSE_TYPE == "ABC")
    .Select(t => new
        {
            value = t.PSP_INDLICENSECLAsse.ID,
            name = t.PSP_INDIVIDUALLICENSE.LICENSE_CLASS,
        })
    .OrderBy(x => x.name);

답변

그것은 같은 것일 수 있습니다

var myvar = from a in context.MyEntity
            join b in context.MyEntity2 on a.key equals b.key
            select new { prop1 = a.prop1, prop2= b.prop1};