2017-10-20 1 views
1

쿼리를 작동 시키려고 시도했지만 정식으로 어떻게 시도했는지 (또는 가능한 경우) 내가 시도한 모든 작업이 제대로 수행되지 않았는지 확실하지 않습니다.AutoMapper를 사용하는 LINQ GroupBy 집계

Person, PersonVote, PersonCategory, Category, City 및 FirstAdminDivision의 총 6 개 테이블 쿼리.

PersonVote는 사람들을위한 사용자 검토 테이블이며 1-5 (5는 "최상"임)를 허용하는 십진수 인 Vote라는 열을 포함합니다. FirstAdminDivision은 캘리포니아와 같은 미국 주와 동의어입니다. Person 테이블에는 City에 대한 외래 키인 CityId라는 열이 있습니다. 내가 믿는 다른 테이블은 대부분 자명하다. 그래서 나는 필요하다면 언급하지 않을 것이다.

내 목표는 특정 개인의 PersonVote 테이블에 대한 모든 투표의 평균을 기반으로하는 "가장 인기있는"사람들의 목록을 반환하는 쿼리를 만드는 것입니다. 예를 들어 한 사람이 3 표를 갖고 3 표가 모두 "5"이면 목록의 첫 번째 항목이됩니다 ...이 시점에서 2 차 순서를 신경 쓰지 마십시오 ... 예를 들어 ... 대부분의 투표와 같습니다. 동점은 "이기"것입니다.

AutoMapper 없이도이 작업을 수행 할 수 있지만 코드가 매우 깨끗하고 읽기 쉽기 때문에 AM의 ProjectTo 확장 방법을 사용하여 프로젝션을 수행하는 기능이 좋아서 가능한 경우 해당 방법을 사용하기를 원하지만 어떤 행운을 얻지는 못했습니다. 일하다.

여기에 내가 할 일이 있습니다 .... 기본적으로 LINQ의 Select 메서드 대신 ProjectTo가 가능한지 확인하려고합니다.

List<PersonModel> people = db.People 
        .GroupBy(x => x.PersonId) 
        .Select(x => new PersonModel 
        { 
         PersonId = x.FirstOrDefault().PersonId, 
         Name = x.FirstOrDefault().Name, 
         LocationDisplay = x.FirstOrDefault().City.Name + ", " + x.FirstOrDefault().City.FirstAdminDivision.Name, 
         AverageVote = x.FirstOrDefault().PersonVotes.Average(y => y.Vote), 
         Categories = x.FirstOrDefault().PersonCategories.Select(y => new CategoryModel 
         { 
          CategoryId = y.CategoryId, 
          Name = y.Category.Name 
         }).ToList() 
        }) 
        .OrderByDescending(x => x.AverageVote) 
        .ToList(); 
+0

당신이 https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions를 시도? – abatishchev

+0

그래, 필자는 설명서를 검토하고 몇 가지 다른 접근 방식을 시도했지만 아직 실제로 작동하는 것은 없습니다. "IGrouping'2에서 PersonModel으로 맵이 누락되었습니다. Mapper.CreateMap "또는이 중 하나를 사용하여 만듭니다. "지정된 유형 멤버 'AverageVote'가 LINQ to Entities에서 지원되지 않습니다. ". 둘 다 무엇인지 이해하지만, 내가 무엇을했는지 또는 AM의 투영법을 사용하여 원하는 것이 무엇인지를 쿼리를 구성하는 방법을 알지 못합니다. – user1011627

+0

AM없이 EF 만 사용하여 원하는 쿼리를 구성하고 실행할 수 있었습니까? – abatishchev

답변

3

코드 샘플을 살펴본 결과 모델을 설정하기 위해 모델을 결정하려고했습니다. 다음 개체 주어진

 Mapper.Initialize(cfg => 
     { 
      cfg.CreateMap<IEnumerable<People>, PersonModel>() 
       .ForMember(
        model => model.LocationDisplay, 
        conf => conf.MapFrom(p => p.FirstOrDefault().City.Name)) 
       .ForMember(
        model => model.AverageVote, 
        conf => conf.MapFrom(p => p.FirstOrDefault().PersonVoes.Average(votes => votes.Vote))); 
     }); 

: 그래서

public class People 
{ 
    public int PeronId { get; set; } 
    public string Name { get; set; } 
    public City City { get; set; } 
    public IList<PersonVotes> PersonVoes { get; set; } 
} 

public class PersonVotes 
{ 
    public int Vote { get; set; } 
} 

public class City 
{ 
    public string Name { get; set; } 
} 

public class FirstAdminDivision 
{ 
    public string Name { get; set; } 
} 

public class PersonModel 
{ 
    public int PersonId { get; set; } 
    public string Name { get; set; } 
    public string LocationDisplay { get; set; } 
    public double AverageVote { get; set; } 
} 

정적 API를 통해 그때 초기화 ProjectTo 확장을 AM 사용하려면 : 난 단지 기능을 보여주기 위해 속성의 몇 가지를 사용하여 구현

var people = new List<People>() 
     { 
      new People 
      { 
       PeronId = 1, 
       City = new City 
       { 
        Name = "XXXX" 
       }, 
       PersonVoes = new List<PersonVotes> 
       { 
        new PersonVotes 
        { 
         Vote = 4 
        }, 
        new PersonVotes 
        { 
         Vote = 3 
        } 
       } 

      } 
     }; 
나는 다음 쿼리 것

:

var result = people 
      .GroupBy(p => p.PeronId) 
      .Select(peoples => peoples) 
      .AsQueryable() 
      .ProjectTo<PersonModel>(); 

저는 메모리 개체를 사용하고 있습니다. 그래서 AM에서 ProjectTo 확장 메서드를 사용하려면 IQueryable로 변환해야합니다.

나는 이것이 당신이 찾고있는 바램입니다. 건배,

엔티티 조회에 LINQ 업데이트 :

var result = db.People 
    .GroupBy(p => p.PersonId) 
    .ProjectTo<PersonModel>(base.ConfigProvider) // AM requires me to pass Mapping Provider here. 
    .OrderByDescending(x => x.AverageVote) 
    .ToList(); 
+0

감사합니다 ODawg ... 이것은 올바른 길로 나를 잡았습니다. 내가 필요한 실제 LINQ 문의 LINQ To Entities 버전을 포함하도록 답변을 업데이트했습니다. 나를위한 열쇠는 게시 한 AM 매핑에있었습니다. – user1011627