2016-07-26 2 views
2

Entity Framework를 사용하여 데이터베이스에 액세스하는 웹 API 프로젝트에서 LINQ를 사용하고 있습니다. 스 캐 폴딩을 사용하여 API 컨트롤러를 만들었습니다.Linq 식의 메서드 사용

웹 API가 EF 모델 클래스를 노출하지 않도록 대신 DTO를 사용합니다. 나는 DTO를 사용하기 위해 컨트롤러 메소드를 수정했고, 특정 엔티티의 모델 클래스와 DTO 사이의 값을 복사하는 "Translate"메소드를 가지고 있으며, 클래스 내의 여러 메소드에서이를 사용합니다.

이 게시물에서는 FirstName, LastName, MiddleName이라는 세 가지 속성을 가진 간단한 Person 클래스를 사용하고 있습니다. 당신이 볼 수있는 리팩토링 기회로 아래의 LINQ 표현의 번역 메소드를 호출하여이있다으로

public IQueryable<PersonDto> GetPersons() 
{ 
    var personDtos = from p in db.Persons 
    order by p.LastName, p.FirstName 
    select new PersonDto() 
    { 
     FirstName = p.FirstName, 
     LastName = p.LastName, 
     MiddleName = p.MiddleName 
    }; 

    return personDtos; 
} 

private PersonDto Translate(Person p) 
{ 
    if (person == null) 
     return null; 

    return new PersonDto() 
    { 
     FirstName = p.FirstName, 
     LastName = p.LastName, 
     MiddleName = p.MiddleName 
    } 
} 

는 :

public IQueryable<PersonDto> GetPersons() 
{ 
    var personDtos = from p in db.Persons 
    order by p.LastName, p.FirstName 
    select Translate(p); 

    return personDtos; 
} 

이 좋은 것 같다 내가 그것을 실행하는 경우를 제외하고, 나는 예외를 얻을 : 엔티티에

LINQ '번역'

이 작품을 만들 수있는 방법이 있나요을하는 방법을 인식하지 못하는 이유는 무엇입니까? 우리의 데이터 모델에있는 몇몇 클래스는 꽤 ​​많은 프로퍼티를 가지고 있기 때문에 가능한 경우 Translate 메소드를 호출하는 것이 좋다.

+0

그것은 예 db.Persons.Where (...)을 위해 사용하기 매우 쉽게, myModel에 엔티티를 전송하는 AutoMapper를 사용하는 투사, 내가 역자 주 사용하는 것이 좋습니다. ProjectTo (). ToList(). –

답변

2

로 변경할 수 있습니다. 한 가지 방법은 AsEnumerable() 전화하여 방법은 오히려

var personDtos = from p in db.Persons.AsEnumerable() 
order by p.LastName, p.FirstName 
select Translate(p); 
+0

이 작업을 수행하려면 personDtos.AsQueryable()을 캐스팅해야합니다. 그러나 큰 문제는 아니지만 db.persons orderby p.LastName, p.FirstName에서 p부터 var persons = using을 사용하는 것만큼이나 효율적인 지 여부는 확실하지 않으며 결과를 반복하고 각각에 대해 translate를 호출합니다. 나는 또한 하나의 Person을 얻기 위해 메소드에서 Translate를 사용할 것이지만 이것을 더 쉽게 찾을 수있다 : var person = await db.Persons.SingleOrDefaultAsync (p => p.id == id); var personDto = 번역 (사람); – DesertFoxAZ

1

LinqToEntities는 메서드 Translate()를 데이터베이스에서 실행할 수있는 것으로 변경하는 방법을 알지 못합니다. 그 처리를 보장합니다 AsEnumerable()는이 호출 된 후 클라이언트 측을 발생합니다

var personDtos = (from p in db.Persons 
    order by p.LastName, p.FirstName 
    select p) 
    .AsEnumerable() 
    .Translate(p); 

는 아주 가까이 있습니다. 그러나 Translate()는 IEnumerable이 아닌 한 사람을 필요로합니다. 이 방법 아무 생각이 없기 때문에 당신은 변환 할 수없는 원인 LINQ to Entities는 SQL 쿼리와 방법으로 표현을 번역하는의

private IEnumerable<PersonDto> Translate(IEnumerable<Person> persons) 
{ 
    if (persons == null) yield break; 

    foreach (var p in persons) 
    { 
     yield return new PersonDto() 
     { 
      FirstName = p.FirstName, 
      LastName = p.LastName, 
      MiddleName = p.MiddleName 
     } 
    } 
} 
-1

당신은 ProjectToAutoMapper의 Queryable에서 확장을 사용할 수 있습니다 LINQ to objects 호출하는 것입니다.

db.Persons.ProjectTo<PersonDTO>().ToList() 
+0

이것은 "링크 전용"답변과 매우 유사합니다. 일부 샘플이나 추가 정보가 도움이 될 것입니다. – DVK

관련 문제